繁体   English   中英

保持承诺链可读

[英]Keeping Promise Chains Readable

我已经习惯了承诺链接数组。 当每个承诺是一个很长的行时,读取一个承诺链是非常容易的

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

这非常容易阅读。 但是,当我使用自定义函数创建承诺链时,它会变得更加混乱。

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 
  })

现在,这可以清晰,但当承诺链进一步延伸时,它会变得有点多。 如果我使每个承诺都是它自己的功能,那么我可以简化流程,所以代码看起来像这样(imo,1000x更易读)。

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

这样,我可以重新排列函数,而无需操纵从一个promise传递到下一个promise的值。 如果一个承诺使用了另一个的结果,它只需要在另一个之后,而不是紧接在另一个之后。 这样我就可以在任何需要的地方偷偷兑现承诺。

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

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

好吧,你可以使用承诺这样的东西:

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

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

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

因为代码如下:

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);
}

然后你没有范围问题,因为你可以轻松访问所有以前分配的变量。

有关支持此语法的节点版本,请参阅此内容:

您可以使用节点V7.6使用+开箱或节点V7.0 +与--harmony标志。

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

如果你真的想要,可以通过自己创建范围将范围限制为单个元承诺:

return new Promise((resolve, reject) => {
  const f1 = () => { /* ... */ };
  const f2 = () => { /* ... */ };
  const f3 = () => { /* ... */ };

  return db.query()
    .then(f1)
    .then(f2)
    .then(f3)
    .then(resolve)
    .catch(reject);
});

但最明显的方法是使用async / await

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM