嵌套请求循环内的请求到另一台服务器

时间:2018-11-02 23:05:06

标签: javascript node.js express

我需要从另一台服务器请求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 :(编辑)

1 个答案:

答案 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
  });