javascript - 异步函数执行顺序

标签 javascript node.js

我有一个写成这样的异步函数:

pool.query(`select id from table1`)
  .then(rows=>{
    pool.query(`selectQuery1`)
      .then(rows=>{
        return pool.query(`selectQuery2`)
      })
    .then(rows=>{
      console.log('First')
      return pool.query(`selectQuery3`)
    })
  })
  .then(rows=>{
    console.log('Second')
    return pool.query(`selectQuery4`)
  })

我在想最后的 .then 应该在其他一切之后触发。但是 console.log 显示

second
first 

我不明白为什么会这样

最佳答案

您并没有将它们全部链接成一个顺序链。

您创建了两条平行且独立的链,因此这只是一场谁先完成的比赛。

在第二个pool.query() 前面添加一个return,事情会变成这样:

pool.query(`select id from table1`)
  .then(rows=>{
    // **** add return here ****
    return pool.query(`selectQuery1`)
      .then(rows=>{
        return pool.query(`selectQuery2`)
      })
    .then(rows=>{
      console.log('First')
      return pool.query(`selectQuery3`)
    })
  })
  .then(rows=>{
    console.log('Second')
    return pool.query(`selectQuery4`)
  });

通过省略 return,您创建了一个独立于父链的完整独立的 promise 链,因此这只是一场比赛,看哪个先完成,所以它最终取决于两条链中各种操作的速度,甚至每次运行时的完成顺序可能都不相同。

仅供引用,如果您真的想要顺序操作,那么通常最好将您的链扁平化为:

fn().then(...).then(...).then(...).then(...)

不是:

fn1().then(function() {
    return fn2(...).then(...).then(...)
}).then(...)

因为前者更清楚您要做什么。如果你有逻辑分支(你没有显示),那么你有时会被迫离开扁平化设计。

展平后的代码如下所示:

pool.query(`select id from table1`).then(rows=>{
    return pool.query(`selectQuery1`);
}).then(rows => {
    return pool.query(`selectQuery2`);    
}).then(rows => {
    return pool.query(`selectQuery3`);
}).then(rows => {
    return pool.query(`selectQuery4`);
}).then(rows => {
    console.log("done");
}).catch(err => {
    console.log(err);
});

或者,使用 async/wait,它可能会更干净:

try {
    let rows1 = await pool.query(`select id from table1`);
    let rows2 = await pool.query(`selectQuery1`);
    let rows2 = await pool.query(`selectQuery2`);
    let rows3 = await pool.query(`selectQuery3`);
    let rows4 = await pool.query(`selectQuery4`);
    console.log("done");
} catch(e) {
    console.log(err);
}

仅供引用,未能从 .then() 处理程序内部返回 promise 链几乎总是一个错误,因为无法向外界传达成功或失败。

我见过的唯一正确决​​定的情况是在某种即发即忘的操作中,比如可能关闭一个文件,如果操作失败,您没有什么可以做的,而您希望其余的操作正常进行而不是等待完成。但这是罕见的异常(exception),而不是规则。

关于javascript - 异步函数执行顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57190999/

相关文章:

javascript - Django-cms 安装,但下拉菜单和其他 JS 不起作用 - 修复的想法?

javascript - 如何使用 jQuery 调整 DIV 行的大小

javascript - JavaScript 中的全局变量

node.js - 如何创建一个正在运行的API端点?

javascript - 垂直滚动菜单 CSS 无法折叠

javascript - 简单的 JQuery slider 无法正常工作

node.js mongodb 如何连接到 mongo 服务器的副本集

node.js - Apache:与 Apache 集成时 Express.js 中出现 502 代理错误

javascript - 当使用它来取消索引 Node 中的关联数组时,如何强制整数字符串表现得像字符串?

javascript - 将 koa 插件添加到 eggjs 框架