往数组push Promise后数组始终为空,Promise.all返回null,请问代码有何问题?
问题核心原因
pool.query是回调风格的异步接口,你代码中给promises数组 push Promise 的逻辑写在pool.query的回调函数内,而同步执行流不会等待异步回调触发,会直接执行到Promise.all(promises)这一步。此时所有查询回调都未执行,promises数组是空的,Promise.all处理空数组会直接返回空数组的兑现结果,和预期逻辑完全不符。- 外层冗余包裹了
new Promise,属于不必要的 Promise 构造函数嵌套,既多余也容易增加逻辑出错概率。 - 代码中
vv、sql等变量未声明直接赋值,会隐式成为全局变量,容易产生变量污染问题。
修复方案
首先将回调式的 pool.query 封装为 Promise 化的调用,统一异步流程管理,修复后的代码如下:
// 封装Promise版本的查询方法,统一异步处理逻辑 const queryPromise = (sql, params) => { return new Promise((resolve, reject) => { pool.query(sql, params, (error, results, fields) => { if (error) { console.log("the error is", error); return reject(error); } resolve(results); }); }); }; searchProductVariant: (start, end, combinations) => { const promises = []; console.log(start, " ", end); for (let i = start; i < start + end; i++) { // 声明局部变量,避免全局污染 const vv = combinations[i - start].product_variant_name.split("_"); console.log("kk", vv); vv.forEach((v) => { const sql = `SELECT id FROM ecommerce.variant_values as varval where varval.value like '${v}'`; // 直接生成查询Promise并push到数组 const queryTask = queryPromise(sql, []) .then(results => { // 加可选链避免results为空时报错 if (results[0]?.id) { console.log("i is ", i); return addProductVariantDetails(i, results[0].id); } return null; }); promises.push(queryTask); }); } console.log(promises); // 此时数组内已经包含所有异步任务的Promise对象 // 直接返回Promise.all结果,不需要额外套new Promise return Promise.all(promises); }
内容的提问来源于stack exchange,提问作者Faizan Afridi
相关产品推荐
相关产品推荐

