那么可不可以优化一下呢?写成一行要注意,因为使用了逗号,避免被认为是函数的参数分割,导致 yes
不被调用,可以加一个括号括起来。最外层的也可以写成一行,外层真写成一行,那就过分了。
function ready() {
let resolveFN, rejectFN
let promise = new Promise(
(resolve, reject) => ([resolveFN, rejectFN] = [resolve, reject])
)
return [resolveFN, rejectFN, promise]
}
// 保存文件
const saveFile = (path, data) => {
const [yes, no, wait] = ready()
jsonfile.writeFile(path, data, e => (e && no(e), yes()))
return wait
}
const sleep = time => {
return wait
}
const exits = path => {
const [yes, no, wait] = ready()
fs.stat(path, (e, stats) => (e && no(e), yes(stats)))
return wait
}
const ensureSavaPath = path => exits(path).catch(() => mkdir(path))
那么继续抽象的话,其实对于这种 node 统一风格的非常容器转换成 promise
,使用 promisify 即可,类似于 Rxjs
的 bindNodeCallback
。
const { promisify } = require('util')
function ready() {
let resolveFN, rejectFN
let promise = new Promise(
(resolve, reject) => ([resolveFN, rejectFN] = [resolve, reject])
)
const sleep = time => {
const [yes, no, wait] = ready()
setTimeout(yes, time)
return wait
}
// 保存文件
const saveFile = promisify(jsonfile.writeFile)
const exits = promisify(fs.stat)
const ensureSavaPath = path => exits(path).catch(() => mkdir(path))
核心逻辑
当下载内容时候,同样适用 craw
提供的爬取内容的规则。
async function downloadText(chapter, crawl, index, opts) {
const { path, charset } = opts
const selector = await buildSelector(chapter.url, charset)
const text = crawl.text(selector)
}