Promises.js 用法疑问:如何保证异步代码按顺序执行?
问题分析与修复方案
嗨,我一眼就看出问题出在哪了——你的代码里有两个核心问题:变量作用域错误和Promise使用方式不当,导致res.render要么提前执行,要么拿不到正确的结果。咱们一步步来修复:
核心问题拆解
- 局部变量无法被外部访问:你在
.then()回调里定义的var results是该函数的局部变量,外面的res.render根本拿不到这个值,最后传的results要么是undefined,要么只有报错时才会被赋值为"Error."。 - 不必要的
Promise.all:你当前只有一个异步操作(TransactionDetails.findAll),完全不需要用Promise.all——它是用来等待多个Promise并行完成的。而且你直接调用Promise.all(promises)时,虽然会等这个Promise完成,但结果变量的作用域已经错了。
修复后的代码(单个异步操作场景)
直接用Promise链式调用就能保证顺序,而且变量作用域也正确:
// 直接链式调用,确保findAll完成后再执行渲染逻辑 TransactionDetails.findAll({ where: { merchant_id: req.session.userId, transaction_verified: 1 } }) .then(transactionDetails => { // 这里拿到查询结果,直接渲染页面 res.render('dashboard', { data: transactionDetails }); console.log(transactionDetails); // 注意:这里要打印的是transactionDetails,不是data(data是模板里的变量) }) .catch(function(error){ res.status(500); console.log("Error at dashboard:" + error); console.log(error); // 渲染错误状态下的页面 res.render('dashboard', { data: "Error." }); });
如果以后需要处理多个异步操作
要是你之后要等待多个Promise完成,再执行渲染,那正确的Promise.all用法应该是这样:
// 定义多个Promise const transactionPromise = TransactionDetails.findAll({ where: { merchant_id: req.session.userId, transaction_verified: 1 } }); const anotherPromise = SomeOtherModel.findAll({ /* 其他查询条件 */ }); // 等待所有Promise完成 Promise.all([transactionPromise, anotherPromise]) .then(([transactionResults, otherResults]) => { // 所有异步操作完成后才会执行这里 res.render('dashboard', { transactionData: transactionResults, otherData: otherResults }); }) .catch(error => { res.status(500); console.log("Error at dashboard:" + error); res.render('dashboard', { data: "Error." }); });
为什么原来的代码会提前执行?
你原来的代码里,Promise.all(promises)确实会等待promises这个Promise完成,但问题是你在.then()里定义的results是局部变量,外面的res.render根本拿不到正确的查询结果——看起来像是提前执行,其实是因为results在外部作用域没有被正确赋值,导致渲染时用了错误的值。
内容的提问来源于stack exchange,提问作者jdotdoe
相关产品推荐
相关产品推荐

