【问题标题】:Javascript promise for loop chain order fail循环链顺序的 Javascript 承诺失败
【发布时间】:2019-02-18 20:08:00
【问题描述】:

我尝试测试 javascript promise 循环链,但失败了,promise 循环不是我希望的顺序,我的示例是这样的(1 组超时,3 个 promise 函数):

//timeout
timeout = function (fn, pkg) {
    var t = setTimeout(function () {
        fn(pkg);
        clearTimeout(t);
    }, 1000);
};
//Promise function
p01 = function (check) {
    return new Promise(function (RS, RJ) {
        var echo = 'Run P01';
        timeout(RS, echo);
    });
};
p02 = function (check) {
    return new Promise(function (RS, RJ) {
        var echo = 'Run P02';
        timeout(RS, echo);
    });
};
p03 = function (check) {
    return new Promise(function (RS, RJ) {
        var echo = 'Run P03';
        timeout(RS, echo);
    });
};

//do for loop test
for (var i = 0; i < 3; i++) {
    p01().then(function (echo) {
        console.log(echo);
        return p02();
    }).then(function (echo) {
        console.log(echo);
        return p03();
    }).then(function (echo) {
        console.log(echo);
        console.log('Done!');
    });
};

循环完成后,记录显示:

(3)Run P01
(3)Run P02
Run P03
Done!
Run P03
Done!
Run P03
Done!

我不知道发生了什么问题,我该如何解决这个问题:

Run P01
Run P02
Run P03
Done!
Run P01
Run P02
Run P03
Done!
Run P01
Run P02
Run P03
Done!

感谢您的帮助!

【问题讨论】:

    标签: javascript loops promise


    【解决方案1】:

    目前,for 循环中的每次迭代都同步 一个接一个地运行。 Promise 链已初始化,但您无需等待它解决,然后继续下一次迭代(并初始化另一个 Promise 链)。

    在每次迭代中将循环放入 async 函数和 await Promise 链中(这样下一次迭代在当前迭代完全完成之前不会开始):

    //timeout
    timeout = function(fn, pkg) {
      var t = setTimeout(function() {
        fn(pkg);
        clearTimeout(t);
      }, 1000);
    };
    //Promise function
    p01 = function(check) {
      return new Promise(function(RS, RJ) {
        var echo = 'Run P01';
        timeout(RS, echo);
      });
    };
    p02 = function(check) {
      return new Promise(function(RS, RJ) {
        var echo = 'Run P02';
        timeout(RS, echo);
      });
    };
    p03 = function(check) {
      return new Promise(function(RS, RJ) {
        var echo = 'Run P03';
        timeout(RS, echo);
      });
    };
    
    //do for loop test
    
    (async () => {
      for (var i = 0; i < 3; i++) {
        await p01().then(function(echo) {
          console.log(echo);
          return p02();
        }).then(function(echo) {
          console.log(echo);
          return p03();
        }).then(function(echo) {
          console.log(echo);
          console.log('Done!');
        });
      }
    })();

    或者有一个你重新分配的外部 Promise 并在每次调用 .then

    //timeout
    timeout = function (fn, pkg) {
        var t = setTimeout(function () {
            fn(pkg);
            clearTimeout(t);
        }, 1000);
    };
    //Promise function
    p01 = function (check) {
        return new Promise(function (RS, RJ) {
            var echo = 'Run P01';
            timeout(RS, echo);
        });
    };
    p02 = function (check) {
        return new Promise(function (RS, RJ) {
            var echo = 'Run P02';
            timeout(RS, echo);
        });
    };
    p03 = function (check) {
        return new Promise(function (RS, RJ) {
            var echo = 'Run P03';
            timeout(RS, echo);
        });
    };
    
    //do for loop test
    let prom = Promise.resolve();
    for (var i = 0; i < 3; i++) {
        prom = prom.then(p01).then(function (echo) {
            console.log(echo);
            return p02();
        }).then(function (echo) {
            console.log(echo);
            return p03();
        }).then(function (echo) {
            console.log(echo);
            console.log('Done!');
        });
    };

    【讨论】:

    • 很好的答案,再次感谢您的帮助
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多