【发布时间】:2018-06-30 06:11:57
【问题描述】:
我正在编写一个 Node.js 脚本来使用测试数据集填充 SQL 数据库。
在下面代码sn-p所示的promise链中(实际代码有点毛茸茸),函数insertData()需要从前一阶段传递过来的db对象。但是,上一阶段dropAndCreateTables() 内部的异步调用使用db 对象但不返回它。我想出了一个解决方案,将 dropAndCreateTables() 中的 Promise 包装到另一个 Promise 对象中,该对象解析为 db 对象。然而:
- 我听说在非库代码中使用
Promise()构造函数是一种反模式,可能会导致微妙且难以诊断的错误 - 听说嵌套
then()-chains 也是一种反模式 - 它不允许我忽略来自
promiseDrop的错误(例如,我不在乎表在删除时是否不存在) - 很丑
问题:
- 是否有更简单、更好、更被社会接受的方法来覆盖承诺的返回值? (在本例中,使用
Promise.all()创建) - 有没有办法重组我的代码以使这个问题不会发生? (即我这里不排除“XY问题”的可能)
代码:
const dropAndCreateTables = (db, startClean) => {
if(startClean) {
const sqlDrop = fs.readFileSync('drop.sql').toString()
const promiseDrop = db.raw(sqlDrop)
const sqlCreate = fs.readFileSync('create.sql').toString()
const promiseCreate = db.raw(sqlCreate)
/********* Problems here? ************************************/
return new Promise((resolve, reject) => { // Ew?
Promise.all([promiseDrop, promiseCreate])
.then(() => {
resolve(db) // Override the returned value
})
.catch(reject)
})
}
return Promise.resolve(db)
}
initDB({ debug: false })
.then((db) => {
return dropAndCreateTables(db, START_CLEAN) // Without my hack this does not return `db`
})
.then((db) => {
return insertData(db, DO_UPSERT) // This needs the `db` object
})
.then(() => {
console.info(`\n${timestamp()} done`)
})
.catch(handleError)
【问题讨论】:
-
确实是复制品。我怎么能错过那个。
标签: javascript node.js ecmascript-6 promise