我是Node.js和Mongoose的初学者。我花了一整天的时间试图通过SO搜索解决问题,但我找不到合适的解决方案。基本上,我使用一个集合中检索到的值来查询另一个集合。为了做到这一点,我正在迭代先前检索结果的循环。
通过迭代,我可以填充我需要的结果。不幸的是,我遇到问题的地方是在数组中收集所需信息之前发回的响应。我知道这可以通过回调/承诺来处理。我尝试了很多方法,但我的尝试并没有成功。我现在正试图利用Q library来促进回调。我真的很感激一些见解。这是我目前陷入困境的部分片段:
var length = Object.keys(purchasesArray).length;
var jsonArray = [];
var getProductDetails = function () {
var deferred = Q.defer();
for (var i = 0; i < length; i++) {
var property = Object.keys(purchasesArray)[i];
if (purchasesArray.hasOwnProperty(property)) {
var productID = property;
var productQuery = Product.find({asin:
productQuery.exec(function (err, productList) {
jsonArray.push({"productName": productList[0].productName,
"quantity": purchasesArray[productID]});
});
}
}
return deferred.promise;
};
getProductDetails().then(function sendResponse() {
console.log(jsonArray);
response = {
"message": "The action was successful",
"products": jsonArray
};
res.send(response);
return;
}).fail(function (err) {
console.log(err);
})
});
我特别能够在jsonArray
数组中发送两个对象中的一个,因为响应是在第一个元素之后发送的。
更新
感谢 Roamer-1888 的回答,我已经能够构建一个有效的JSON响应,而不必担心在发送响应后设置标头的错误。
基本上,在getProductDetails()
函数中,我尝试从映射purchasesArray
中每个项目的数量时从Mongoose查询中检索产品名称。从函数中,最终,我想形成以下响应:
response = {
"message": "The action was successful",
"products": jsonArray
};
其中,jsonArray
的格式如下getProductDetails
:
jsonArray.push({
"productName": products[index].productName,
"quantity": purchasesArray[productID]
});
答案 0 :(得分:1)
假设purchasesArray
是先前查询的结果,您似乎正在尝试:
purchasesArray
项目purchasesArray
项中派生的数据。如果是这样,并且几乎没有其他猜测,那么以下模式应该可以胜任:
var getProductDetails = function() {
// map purchasesArray to an array of promises
var promises = purchasesArray.map(function(item) {
return Product.findOne({
asin: item.productID // some property of the desired item
}).exec()
.then(function product {
// Here you can freely compose an object comprising data from :
// * the synchronously derived `item` (an element of 'purchasesArray`)
// * the asynchronously derived `product` (from database).
// `item` is still available thanks to "closure".
// For example :
return {
'productName': product.name,
'quantity': item.quantity,
'unitPrice': product.unitPrice
};
})
// Here, by catching, no individual error will cause the whole response to fail.
.then(null, (err) => null);
});
return Promise.all(promises); // return a promise that settles when all `promises` are fulfilled or any one of them fails.
};
getProductDetails().then(results => {
console.log(results); // `results` is an array of the objects composed in getProductDetails(), with properties 'productName', 'quantity' etc.
res.json({
'message': "The action was successful",
'products': results
});
}).catch(err => {
console.log(err);
res.sendStatus(500); // or similar
});
您的最终代码将在细节上有所不同,特别是在组合对象的构成方面。不要依赖我的猜测。