javascript - 保持 Promise 链的可读性

标签 javascript node.js es6-promise

我已经习惯了 promise 链接数组。当每个 promise 都是一行长时,读取 promise 链非常容易,例如

myArray.map(x => convertX)
  .filter()
  .whatever()
  .etc()

这非常容易阅读。然而,当我使用自定义函数创建 promise 链时,它会变得更加困惑。

database.query(first query)
  .then(results => {
    // do stuff
    // do more
    // even more
    return database.query(second query)
  })
  .then(results => {
    // rinse and repeat
  })
  .catch(err => { 
    // error handling 
  })

现在,这可能是清晰的,但是当 promise 链进一步延伸时,它就会变得有点多。如果我让每个 promise 都有自己的功能,那么我可以简化流程,使代码看起来像这样(在我看来,可读性提高了 1000 倍)。

db.query(first query)
  .then(storeFirstQuery)
  .then(secondQueryAndStoreIt)
  .then(thirdQueryAndStoreIt)
  .catch(errHandlingFunction)

这样,我就可以重新排列函数,而不必操作从一个 promise 传递到下一个 promise 的值。如果一个 Promise 使用另一个 Promise 的结果,它只需要在另一个 Promise 之后,但不必紧跟在另一个 Promise 之后。这样我就可以在任何需要的地方偷偷 promise 。

但是,这要求我的 promise 链使用每个 promise 范围之外的变量。有没有经过验证的正确方法可以做到这一点?

编辑 - 似乎 async/await 是执行此操作的最佳方法,但我在 Heroku 上运行 Node,但尚不支持它:/

最佳答案

好吧,你可以使用类似的 promise :

myArray.map(x => convertX)
  .filter()
  .whatever()
  .etc()

如果你使用我的rsp来自 npm 的模块。

除此之外,您还可以使用 ES2017 的 async/await 功能来简化 Promise 链,尤其是它们的范围。

因为使用这样的代码:

db.query(first query)
  .then(storeFirstQuery)
  .then(secondQueryAndStoreIt)
  .then(thirdQueryAndStoreIt)
  .catch(errHandlingFunction)

如果您需要在最后一个 thirdQueryAndStoreIt() 处理程序中使用第一个查询的结果,则在访问超出范围的数据时会遇到问题。但是当你这样做时:

try {
    let a = await db.query(first query);
    let b = await storeFirstQuery();
    let c = await secondQueryAndStoreIt();
    let d = await thirdQueryAndStoreIt(a); // use 'a' here
} catch (e) {
    errHandlingFunction(e);
}

那么您就不会遇到范围问题,因为您可以轻松访问所有先前分配的变量。

查看支持此语法的 Node 版本:

您可以将其与开箱即用的 Node v7.6+ 或带有 --harmony 标志的 Node v7.0+ 一起使用。

对于较旧的 Node 版本,您可以使用 coBluebird.coroutine对于使用生成器函数和 yield 而不是 await 的类似语法。

关于javascript - 保持 Promise 链的可读性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42765589/

相关文章:

sql - NodeJS JSON 数组过滤

javascript - 过滤/恢复 Promise.all 结果

javascript - typescript 检查 promise 正文是否未调用 `resolve`

javascript - 如何在进度条上叠加可填写的检查点

javascript - imagepicker jQuery 回调被点击

javascript - nodeJS语法错误: unexpected token this

javascript - 测试 js 模块,Promise.all

javascript - HTML/JS 调试器

javascript - CircleCi 在 10 分钟后超时

node.js - 在express.js中设置服务器超时