为了账号安全,请及时绑定邮箱和手机立即绑定

异步函数执行顺序

异步函数执行顺序

慕姐8265434 2021-08-20 18:29:15
我有一个异步函数,它是这样写的: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节目secondfirst 我不明白为什么会这样
查看完整描述

2 回答

?
Qyouu

TA贡献1786条经验 获得超11个赞

您没有将它们全部链接到一个顺序链中。


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


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


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,您创建了一个独立于父链的完整独立的承诺链,因此这只是一场竞赛,看看哪个先完成,因此最终取决于两个链中各种操作的速度,并且可能甚至每次运行时的完成顺序都不同。


仅供参考,如果您真的想要顺序操作,那么通常最好将您的链展平为:


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);

});

或者,使用异步/等待,它可能更干净:


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()处理程序内部返回承诺链几乎总是一个错误,因为无法将成功或失败传达给外部世界。


我见过的唯一一个正确决定的情况是在某种类型的火灾和忘记操作中,例如可能关闭文件,如果操作失败并且您希望操作的其余部分正常进行,则没有什么可做的不要等待完成。但这是罕见的例外而不是规则。



查看完整回答
反对 回复 2021-08-20
?
回首忆惘然

TA贡献1847条经验 获得超11个赞

正如其他人所说,技术问题是您缺少 return 语句。但是,您还使用了非起始样式的缩进,这会使您的意图不那么清晰,并且更难发现错误。


这是您的代码,其中添加了一些换行符和缩进更改。这个想法是,a) 链接的方法调用应该总是多行的,每个链都在相同的缩进级别,b) 使用块的箭头函数应该总是缩进比它们存在的范围高一级。


pool

    .query(`select id from table1`)

    .then(rows => {

        // FIX: add 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`);

    });


以这种方式显示时,更容易发现前面pool没有 a 的一个内部用途return。


查看完整回答
反对 回复 2021-08-20
  • 2 回答
  • 0 关注
  • 202 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号