将两个回调合并为一个返回

时间:2019-07-12 06:26:28

标签: javascript node.js serverless-framework

所以我有以下代码:

module.exports.getEstimate = (event, context, callback) => {
 var data = JSON.parse(event.body);

 lalamove.getQuotation(data ,context, function(err, llm_data){
  callback(null,llm_data)
 });
};

因此它将调用lalamove.getQuotation函数并返回一个对象:

{ "totalFee": "108", "totalFeeCurrency": "PHP" }

现在,我添加了一个新函数,该函数返回该对象:

{ "totalFee": "10", "totalFeeCurrency": "PHP" }

从另一个函数开始,所以我认为我应该将它们压入一个数组中,然后在那时候我将调用回调函数,但它不起作用,这就是我尝试过的

module.exports.getEstimate = (event, context, callback) => {
var data = JSON.parse(event.body);
var response = []

lalamove.getQuotation(data ,context, function(err, llm_data){
  const llm_obj = { "lalamove": llm_data }
  response.push(llm_obj);
});

inhouse.getQuotation(data ,context, function(err, ih_data){
  const ih_obj = {"inhouse": ih_data }
  response.push(ih_obj);
});

callback(null,response);
};

我想成为的回应是这样的:

["lalamove": { "totalFee": "108", "totalFeeCurrency": "PHP" },
"inhouse": { "totalFee": "10", "totalFeeCurrency": "PHP" }]

我在做什么错了?

4 个答案:

答案 0 :(得分:4)

您的callback(null,response)不会等待这两个回调函数完成。您可以使用Promise并使用Promise.all(objs).then(function)等待所有的诺言完成并运行。

答案 1 :(得分:2)

尝试将两个引号调用包装在Promise中,然后利用Promise.all等待它们都完成,然后将结果返回到callback

module.exports.getEstimate = (event, context, callback) => {
    let data = JSON.parse(event.body);

    // wrap quotation calls in `Promise`
    Promise.all([
        new Promise(resolve => lalamove.getQuotation(data, context, (err, lalamove) => resolve({ lalamove }))),
        new Promise(resolve => inhouse.getQuotation (data, context, (err, inhouse ) => resolve({ inhouse  }))),
    ]).then(response => {
        // return the result back to `callback`
        callback(null, response);
    })
};

答案 2 :(得分:2)

欢迎来到世界的Javascript世界-回调地狱。

对于您的情况,我们有一些选择:回调地狱,异步lib,Promise,异步/等待...

回调地狱:在回调中调用异步函数

module.exports.getEstimate = (event, context, callback) => {
  var data = JSON.parse(event.body);
  var response = []

  lalamove.getQuotation(data, context, function (err, llm_data) {
    const llm_obj = { "lalamove": llm_data }
    response.push(llm_obj);

    // lalamove.getQuotation done!
    // call next action
    inhouse.getQuotation(data, context, function (err, ih_data) {
      const ih_obj = { "inhouse": ih_data }
      response.push(ih_obj);

      // inhouse.getQuotation done!
      // call the last action
      callback(null, response);
    });
  });
};

异步库:async 您可以使用waterfall函数按顺序执行操作,如果顺序无关紧要,可以使用parallel

module.exports.getEstimate = (event, context, callback) => {
  var data = JSON.parse(event.body);
  var response = []

  async.parallel([
    function (next) {
      lalamove.getQuotation(data, context, function (err, llm_data) {
        // TODO: check err object
        const llm_obj = { "lalamove": llm_data }
        response.push(llm_obj);

        // lalamove.getQuotation done!
        // do next action
        next();
      });
    },
    function (next) {
      inhouse.getQuotation(data, context, function (err, ih_data) {
        const ih_obj = { "inhouse": ih_data }
        response.push(ih_obj);

        // inhouse.getQuotation done!
        // do next action
        next()
      });
    }
  ], function (err) {
    // TODO: check err object
    // call the last action
    callback(null, response);
  });
};

答案 3 :(得分:1)

您还可以尝试使用util.promisify和async / await语法。

例如:

const util = require("util");

module.exports.getEstimate = async (event, context, callback) => {
    let data = JSON.parse(event.body);
    try { 
        let response = await Promise.all([ util.promisify(lalamove.getQuotation)(data, context), 
                                           util.promisify(inhouse.getQuotation)(data, context) ]);
        callback(null, response);
    } catch (err) {
        callback(err);
    }
};

我们也可以做类似的事情,但是没有异步/等待:

const util = require("util");

const getEstimate = (event, context, callback) => {
    let data = JSON.parse(event.body);
    Promise.all([util.promisify(lalamove.getQuotation)(data, context), 
                util.promisify(inhouse.getQuotation)(data, context)])
        .then(response => callback(null, response))
        .catch(err => callback(err));
};