异步回调 Array.map()
Asynchronous Callback to Array.map()
几周前我才开始学习Node.js....我无法理解为什么'products'数组包含null 而不是所需的对象....
在第 13 行,当我在控制台记录对象时,我得到了想要的对象,但我不明白为什么当我在第 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
});
}
}
);
});
};
第 8 行,order.products.map
returns 一个空数组。因为这是一个异步映射。对于每个产品,您都在调用 Series.findById
这是一个承诺,它只有 returns 它解析时的值。由于您不等待解决承诺,因此它在每次迭代中 returns null。
你必须先映射所有的承诺,然后调用 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
});
}
}
);
});
};
几周前我才开始学习Node.js....我无法理解为什么'products'数组包含null 而不是所需的对象....
在第 13 行,当我在控制台记录对象时,我得到了想要的对象,但我不明白为什么当我在第 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
});
}
}
);
});
};
第 8 行,order.products.map
returns 一个空数组。因为这是一个异步映射。对于每个产品,您都在调用 Series.findById
这是一个承诺,它只有 returns 它解析时的值。由于您不等待解决承诺,因此它在每次迭代中 returns null。
你必须先映射所有的承诺,然后调用 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
});
}
}
);
});
};