蓝鸟,承诺,然后()

Posted

技术标签:

【中文标题】蓝鸟,承诺,然后()【英文标题】:Bluebird, promises and then() 【发布时间】:2014-02-13 09:52:57 【问题描述】:

我只使用了几天的 bluebird,但我想回顾一下我所有的旧代码和promisify it :)

我的问题是我还没有完全掌握then()命令的流程。

考虑这两个块:

一个

methodThatReturnsAPromise().then(task2).then(task3);

B

var promise = methodThatReturnsAPromise();
promise.then(task2)
promise.then(task3);

    在场景 A 中 task3 会得到 task2 的结果吗?在 B 中他们都得到了第一个承诺的结果?

    第二个与从 bluebird 运行 Promise.all 有何不同?

    在使用 catch 方法时,这些 A/B/Promise.all 有何不同(我把它放在哪里)。

抱歉,这是一堆问题。

【问题讨论】:

你会如何运行Promise.all @Bergi github.com/petkaantonov/bluebird/blob/master/… 这是.all @BenjaminGruenbaum:我很清楚它的作用,我问过 OP 他将如何应用它。 【参考方案1】:

欢迎来到美妙的承诺世界。

then 在您的示例中的工作原理

您在1 中的断言是正确的。我们可以在 Bluebird 中使用 Promise.resolve 对一个值模拟一个 Promise 解析。

让我们展示一下:

让我们得到一个返回承诺的函数:

function foo()
    return Promise.resolve("Value");    


foo().then(alert);

这个简短的 sn-p 将提醒 "Value" 为 we can see。

现在,让我们再创建两个 Promise,每个 Promise 发出警报并返回不同的值。

function task2(e)
    alert("In two got " + e);
    return " Two ";

function task3(e)
    alert("In three got " + e);
    return " Three ";

所以,正如您在your first code 中看到的那样,它确实会在一个链中解析,每个都具有前一部分的值。

在第二个例子中,task2 和 task3 都会得到相同的值,也会一起执行(也就是说,task 3 不会等待 task 2)。你可以看到here。

Promise.all

Promise.all(或者只是从 then 实现处理程序返回一个数组,然后使用 .spread)用于等待多个结果全部完成。在您的示例中,您将单个结果挂钩到多个部分。

捕获

你总是把 catch 放在你想捕获错误的地方。正如您通常在同步代码中所做的那样。只要记住总是抛出一个承诺或承诺的代码。

【讨论】:

所以我可以将捕获放在链上的任何位置,它会捕获任何传播的错误吗?如果我在链条上的任何地方重新投掷,我可以稍后再接回来? @Madd0g 是的。就像使用普通的 try/catch 块一样。 太棒了。我想我之前试图捕获一个重新抛出的错误,但它没有用,但这可能是我的错,我会再试一次。感谢您的出色回答【参考方案2】:

在场景A task3 会得到task2 的结果吗?在 B 中他们都得到了第一个承诺的结果?

是的。

第二个与从 bluebird 运行 Promise.all 有何不同?

您不会将(并行)任务 2 和 3 的结果提取到新的 Promise 中。

在使用 catch 方法时,这些 A/B/Promise.all 有何不同(我把它放在哪里)。

通常你会把它放在链的末端,除非你想捕获一个特定的错误。

promise.catch()
// handles rejections of this promise

promise.then(task2).catch()
// handles rejections from either promise or task2
// if promise is rejected, task2 will not be executed

Promise.all(promise.then(task2), promise.then(task3)).catch()
// handles rejections from any.
// if promise is rejected, neither task2 nor task3 will be executed
// if task2 or task3 throw, the error will immediately handled
// and the other task will not be affected (but its result is unavailable)

【讨论】:

我想我确实主要了解它是如何工作的。非常直观,我希望我能回到过去,抹去我与回调和金字塔作斗争的几个月:) 感谢您的回答。我会把答案奖励给另一个人,因为他速度更快,并且做了那些很棒的 jsfiddles,但是有一个赞成票 - 很好的答案【参考方案3】:

你没有得到一个简单的原则链接

在第一个可以写成

var promise   = methodThatReturnsAPromise(),
    promise1  = promise.then(task2);
promise1.then(task3);

第二种情况

var promise   = methodThatReturnsAPromise();
promise.then(task2)
promise.then(task3);

希望这能解释两者的区别

【讨论】:

以上是关于蓝鸟,承诺,然后()的主要内容,如果未能解决你的问题,请参考以下文章

蓝鸟承诺未定义?

处理嵌套承诺的最佳方法(蓝鸟)[重复]

与蓝鸟的承诺链阵列

蓝鸟嵌套承诺与每个/传播

使用蓝鸟承诺的while循环

蓝鸟承诺“promisifyAll”不起作用 - 无法读取属性“then”