异步函数未按顺序执行

时间:2020-01-23 09:59:05

标签: javascript node.js asynchronous promise

我的代码行为异常。这是一个代码片段及其输出:

  let files = //files is an array

  Promise.each(files, file => {
    return epub.file(file.name).async('string').then(content => {
        let mmls = //mmls is an array

        Promise.each(mmls, mml => {
          return mj.typeset({math: mml, format: 'MathML', svg: true}).then(mjdata => {
            // do something
          })
        }).then(() => {
          console.log(0)
        })
    })
  }).then(() => {
    console.log(1)
  })

它将登录控制台:

0
0
0
0
0
0
0
1
0  // one '0' after '1'

我发现奇怪的是,如果已经记录了“ 1”,那么最后一个“ 0”是如何记录的?

仅供参考:我正在使用蓝鸟。

1 个答案:

答案 0 :(得分:2)

如果没有正确地链接您的诺言,说两个诺言都需要1秒才能执行:

somePromise.then(() => {
    // 1.
    someOtherPromise.then(() => {
        // 3.
        console.log("inner");
    });
}).then(() => {
    // 2.
    console.log("outer");
});

首先,1.将在t + 1秒后出现。然后,它触发someOtherPromise,但不等待它,因此1.“同步”完成,导致2.被执行(在t + 1s +Ɛns处)。在t + 2s处执行3.。但是,如果您确实等待另一个承诺:

somePromise.then(() => {
    // 1.
    return someOtherPromise.then(() => {
        // 2.
        console.log("inner");
    });
}).then(() => {
    // 3.
    console.log("outer");
});

首先,1.将在t + 1秒后出现。然后,它触发someOtherPromise,但确实等待它:3.仅在返回的诺言得到解决后才被调用。因此2.发生在t + 2s,然后3.发生在t + 2s +Ɛns。

旁注:在函数世界中,您通常有.map.flatMap,但是JS Promise的.then会根据回调由于动态类型返回的内容而将两者混合使用。