JavaScript 串行 Promise 与 setTimeout

标签 javascript promise bluebird es6-promise

我正在致力于构建带有 setTimeouts 的 Promise 链。所有 Promise 都需要串联而不是并行运行。我正在使用 Bluebird 模块来实现 Promise 执行的串行流程。

有人可以解释一下为什么这段代码给我的输出是 1,2,3,4 而不是 4,3,2,1?

var bluebirdPromise = require('bluebird');

function p1(value) {
    return new Promise(function(resolve, reject) {
       setTimeout(function(resolve) {
           console.log(value);
           resolve;
       }, value * 1000);
    });
}

var arr = [p1(4), p1(3), p1(2), p1(1)];

bluebirdPromise.reduce(arr,
    function(item, index, length) {

    }).then(function (result) {

    });

最佳答案

有几个问题:

  • 您拥有的 console.log 并不依赖于之前已解决的 promise 。只有超时决定何时输出发生。当您在“同一”时间创建所有四个 Promise 时,因此所有四个 setTimeout 调用都会同时调用,它们的回调在确定的超时时调用。之后如何链接 Promise 并不重要...要解决这个问题,您需要将 console.log 移动到 then 回调中,因为该回调只会被执行当链中的前一个 promise 得到解决时。

  • 您的代码中未调用 resolve 函数。您需要添加括号。

  • setTimeout 回调的解析参数隐藏了同名的real函数:您需要删除该参数。

这是建议的更正。对于此代码片段,我已将 bluebird reduce 替换为标准 Array#reduce,但它的工作方式与 bluebird 的 reduce 类似:

function p1(value) {
    return new Promise(function(resolve, reject) {
       setTimeout(function() { // ***
           resolve(value); // ***
       }, value * 1000);
    });
}

var arr = [p1(4), p1(3), p1(2), p1(1)];

arr.reduce(function(promise, next) {
    return promise.then(_ => next).then( value => {
        console.log(value); // ***
        return value;
    });
}, Promise.resolve());

关于JavaScript 串行 Promise 与 setTimeout,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43819894/

相关文章:

javascript - Celery+Django -- 使用 Django 消息框架轮询任务状态并报告成功或失败

javascript - 如何使用 Bluebird Promises 进行分页?

javascript - 使用requirejs为chrome扩展创建bluebird promise 时出错

javascript - for 循环中的嵌套 Promise 的行为不符合预期

node.js - OpenWhisk/Node —— Promise 未解决

angularjs - 将 AngularJS 延迟 promise 转换为 JSOM 的 AngularX observable

javascript - 按顺序遍历未确定数量的 Promise

javascript - 在另一个 promise 失败的情况下解决 promise

javascript - Bower 安装不运行 "install"步骤

javascript - Visual Studio 2013 的最低 Telerik 版本 ASP AJAX