Array.map() 的异步回调
Posted
技术标签:
【中文标题】Array.map() 的异步回调【英文标题】:Asynchronous Callback to Array.map() 【发布时间】:2021-06-24 03:36:22 【问题描述】:几周前我刚刚开始学习 Node.js.... 我无法理解为什么 'products' 数组包含 null 而不是想要的对象....
在第 13 行,当我在控制台记录对象时,我得到了所需的对象,但我不明白为什么当我在 map 函数之后在第 40 行控制台记录它们时它们是 null完成了它的执行......
如果数组长度为 2(这应该意味着成功推送)为什么存储在里面的对象仍然是 null 而不是我想要存储的对象?
控制台输出
订单架构
exports.getOrders = async (req, res, next) =>
const userOrders = [];
Order.find( 'user.userId': req.user._id ).then((orders) =>
console.log(orders); // Line 4
async.eachSeries(
orders,
function (order, callback)
const products = order.products.map((p) =>
const seriesId = p.product.seriesId;
const volumeId = p.product.volumeId;
Series.findById(seriesId).then((series) =>
const volume = series.volumes.id(volumeId);
console.log(volume, p.quantity); // Line 13
return
seriesTitle: volume.parent().title,
volume: volume,
quantity: p.quantity
;
);
);
console.log('Product Array Length: ', products.length); // Line 21
if (products.length !== 0)
const data =
productData: products,
orderData:
date: order.date,
totalPrice: order.totalPrice
;
userOrders.push(data);
callback(null);
else
callback('Failed');
,
function (err)
if (err)
console.log('Could not retrieve orders');
else
console.log(userOrders); // Line 40
res.render('shop/orders',
docTitle: 'My Orders',
path: 'orders',
orders: userOrders,
user: req.user
);
);
);
;
【问题讨论】:
不要将 async.js 回调样式与 Promise 混用。您已经在使用async
/await
语法,所以只需编写一个循环而不是使用async.eachSeries
。
【参考方案1】:
在第 8 行,order.products.map
返回一个空数组。因为这是一个异步映射。对于每个产品,您都在调用Series.findById
,这是一个承诺,它只在解析时返回值。由于您不等待承诺解决,因此它在每次迭代时返回 null。
你必须先映射所有的promise,然后调用Promise.all
来解决它们,然后你会得到期望的值。
exports.getOrders = async (req, res, next) =>
const userOrders = [];
Order.find( 'user.userId': req.user._id ).then((orders) =>
console.log(orders); // Line 4
async.eachSeries(
orders,
function (order, callback)
const productPromise = order.products.map((p) =>
const seriesId = p.product.seriesId;
const volumeId = p.product.volumeId;
//ANSWER: Return the following promise
return Series.findById(seriesId).then((series) =>
const volume = series.volumes.id(volumeId);
console.log(volume, p.quantity); // Line 13
return
seriesTitle: volume.parent().title,
volume: volume,
quantity: p.quantity
;
);
);
// ANSWER: call all the promises
Promise.all(productPromise)
.then(function(products)
console.log('Product Array Length: ', products.length);
if (products.length !== 0)
const data =
productData: products,
orderData:
date: order.date,
totalPrice: order.totalPrice
;
userOrders.push(data);
callback(null);
else
callback('Failed');
);
,
function (err)
if (err)
console.log('Could not retrieve orders');
else
console.log(userOrders); // Line 40
res.render('shop/orders',
docTitle: 'My Orders',
path: 'orders',
orders: userOrders,
user: req.user
);
);
);
;
【讨论】:
非常感谢您的解释,它有效.... ^__^以上是关于Array.map() 的异步回调的主要内容,如果未能解决你的问题,请参考以下文章