我需要从另一台服务器请求X个产品,并且我需要等待执行完成才能继续将订单保存到数据库中。 假设我通过邮寄收到需要添加到订单中的一系列产品ID,例如
JSON FILE:
{
"order_products":[1,2,3,4]
}
这是一个代码示例:
//Express module
var router = require('express').Router();
//HTTP Request module
var client = require('request');
//Util that saves the URLs of the other databases
var productURL = require('../utils/product/productURL');
//Builds a product object given a JSON
var productBuilder = require('../utils/product/productBuilder');
router.post('/', req, res) {
//Instantiate a new order
var orderInstance = new order({
date: Date.now
});
//Query the products in the other server and add them to the order
req.body.order_products.forEach(id => {
client.get(productURL.HTTPS + id, { json: true }, (err, res, JSONProduct) => {
var product = productBuilder.build(JSONProduct);
orderInstance.order_products.push(product);
});
};
//Save the order in the database
orderInstance.save(....);
//Send response
res.status(201).json(orderInstance);
}
这里的问题是,当循环仍在执行时,将发送响应(201),并且orderInstance被保存而没有任何乘积。如果我console.log产品,则它们仅在orderInstance保存后出现。 我尝试实现回调来解决此问题,但没有成功。如果有人可以在这里帮助我,我将不胜感激!在此先感谢:smiley :(编辑)
答案 0 :(得分:1)
forEach
同步运行 -当forEach
结束时,client.get
请求可能已经全部发出,但是响应肯定没有回来然而。您需要将每个请求转换为Promise
,然后在这些Promises的数组上调用Promise.all
。一旦所有回复都返回,Promise.all
将解决。例如:
const allPromises = req.body.order_products.map(id => new Promise((resolve, reject) => {
client.get('productURL.HTTPS' + id, { json: true }, (err, res, JSONProduct) => {
if (err) reject (err);
else resolve(productBuilder.build(JSONProduct));
});
}));
Promise.all(allPromises)
.then((newProducts) => {
orderInstance.order_products.push(...newProducts);
res.status(201).json(orderInstance);
})
.catch((err) => {
// handle errors
});