Node Js Async 未按正确顺序运行并跳过承诺

Posted

技术标签:

【中文标题】Node Js Async 未按正确顺序运行并跳过承诺【英文标题】:Node Js Async doesnt run in the Correct order and Skips promises 【发布时间】:2021-11-29 02:00:25 【问题描述】:

我目前在使用 async/await 语法时遇到问题。在过去的 2 天里,我试图找出原因,最后决定问一下。

我正在尝试运行一个 cron 函数(测试),该函数调用连接到数据库的异步函数,并尝试使用 3rd 方 API 查找有关每个条目的新信息。

每个函数都独立工作,但在组合它们时它们不会以正确的顺序运行,第一个函数会跳过第一行的 await 语句。(仍然执行它)

输出如下所示(未定义 -> DB 条目 -> api 结果)

正确的应该看起来像(数据库条目 -> api 结果 -> 最终结果)

async function test() 
    var db = await checkfornewdata() // executes 
    console.log(db) //skips line one and returns undefined as it didnt get its value

async function checkfornewdata()

    
    var state = `SELECT * FROM users`;
    var users= []
    var newusers

    console.log('Get connection ...');

     connection.query(state , async function (err,result) 
      if(err) throw err;
      users= result
     console.log('Query Result')
     console.log(result) //works without problems

     for (var i in result) 

       var checknew= await 3rdpartyapi.getusers(i.id );
       if (i.joinDate> checknew.joinDate)
         newusers.push(i);
     
     console.log('New entries:')
     console.log(newusers)
     connection.end()
     return newusers;
  
async function getusers(id)

var joinDate;   

if (typeof(id) !== 'undefined')

console.log("getting joinDate of " + id)
await 3rdpartyapi.getUser(id).then(User =>     
        
joindate= User.joinDate;
console.log(joinDate)   //last output i recieve

)
.catch((err) => 
    
console.log(err)    

return err;
)
return joinDate;

【问题讨论】:

为什么你把 promise 和 async-await 混为一谈。将所有 promise 转换为 async await 并将函数内的所有代码添加到 try-catch。你会在 catch 中得到错误。还有这个元素 checkfornewdata 函数是什么? 我修复了它,我不小心在那里复制了一个错误的提交,到处都是它的结果。承诺功能来自 3rd 方网站,我只是复制和修改了一点 【参考方案1】:

在您的checkfornewdata 函数中,您混合了承诺和回调。在当前形式中,您的函数在对数据库的调用完成之前返回。 (这就是为什么console.log(db) 返回undefined)。

要解决此问题,您可以使用支持承诺的 mysql 驱动程序(如 mysql2)或像这样重写您的函数:

function checkfornewdata() 
    // ...    
    return new Promise((resolve, reject) => 
      connection.query(state , async (err, result) => 
        if (err) 
          return reject(err);
        
        // ...
        resolve(newusers);
      
    

【讨论】:

谢谢,我把所有东西都写到了 mysql2,现在我使用的语法可以工作了,非常感谢

以上是关于Node Js Async 未按正确顺序运行并跳过承诺的主要内容,如果未能解决你的问题,请参考以下文章

Node.js express.json 中间件未按预期解析请求

使用 Javascript(以及 Node.js)使用 async/await 和 Promises 的正确方法是啥 [重复]

ViewDidLoad 未按正确顺序执行操作 - Firebase、Swift

运行connectedAndroidTest并跳过卸载

如何将测试标记为“长”并跳过它们?

使用 Promise 并跳过代码时,Mocha 测试超时,为啥?