在瀑布中链接承诺

Posted

技术标签:

【中文标题】在瀑布中链接承诺【英文标题】:Chaining promises in a waterfall 【发布时间】:2017-03-27 13:37:57 【问题描述】:

我一直在尝试几种不同的方法来链接一组函数,但似乎找不到我特别喜欢的方法。以下是我最后确定的,但仍然不热衷。

有人可以建议一个更简洁的模式吗?我不想选择 Async.js 或库。

[
  this.connectDatabase.bind(this),
  this.connectServer.bind(this),
  this.listen.bind(this)
].reduce(
  (chain, fn) => 
    let p = new Promise(fn);
    chain.then(p);
    return p;
  ,
  Promise.resolve()
);

附言。任何其他提示都非常受欢迎。

【问题讨论】:

【参考方案1】:

在 *** 上找到了这个关于如何动态链接承诺的解决方案:

iterable.reduce((p, fn) => p.then(fn), Promise.resolve())

完整的帖子在这里:https://***.com/a/30823708/4052701

【讨论】:

干净整洁。谢谢! 嗯,刚刚用我的实现试了一下,看起来它被简化了,因为它将promise的生成移到了单独的函数中。想知道是否有什么可以完全避免这种情况。不过现在就可以了=) 这很漂亮:)【参考方案2】:

ES7 异步/等待呢? 您的代码中有奇怪/旧的 bind(this),但不要与您的示例混淆。

async function x() 
    try 
        await this.connectDatabase.bind(this);
        await this.connectServer.bind(this);
        await this.listen.bind(this);
     catch(e) 
        throw e;
    

或更通用的

async function () 
    for (let item of yourArray) 
        try 
            await item.bind(this); //strange bind of your code.
         catch(e) 
            throw e;
        
    

【讨论】:

是的,我更喜欢这样做。还没接触过 ES7,害怕升级我们的代码库。绑定就在那里,因为我还没有学习一个新的/更好的模式来引用我的类中的类方法。在这种情况下,connectDatabase 是我的类中的一个方法,然后使用对类中其他方法的引用。如果我不将方法调用绑定到 this,它就会失去它的上下文。建议? 你能分享一些工作沙箱吗?如果 connectServer 失败我不想听怎么办? @codeofnode 我通过添加 try-catch 更新了我的答案。您的最后一个问题可以通过 try-catch 围绕 connectServer 方法来完成:尝试 await this.connectServer.bind(this);catch(e)//don't throw to continue。如果不想等待connectServer,可以去掉await。

以上是关于在瀑布中链接承诺的主要内容,如果未能解决你的问题,请参考以下文章

如何在 knex.js 迁移中链接承诺

在 for 循环中链接猫鼬承诺

链接承诺,或一个承诺触发另一个

将承诺的结果链接并传递给进一步的承诺[重复]

如何在 JS 中使用 try、catch、.then 链接和异步等待来解决承诺?

链接承诺不会将数据从一个 .then 传递到下一个