[英]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版本,您可以使用co或Bluebird.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.