最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Combine two callbacks into one return - Stack Overflow

programmeradmin0浏览0评论

So I have this code:

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

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

So it calls lalamove.getQuotation function and returns an object:

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

Now, I have added a new function, that returns this object:

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

from a different function so I thought I should push them in one array and then that is when I would call the callback but it does not work, this is what I have tried

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

and what I want to be the response is like this:

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

what am I doing wrong?

So I have this code:

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

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

So it calls lalamove.getQuotation function and returns an object:

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

Now, I have added a new function, that returns this object:

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

from a different function so I thought I should push them in one array and then that is when I would call the callback but it does not work, this is what I have tried

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

and what I want to be the response is like this:

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

what am I doing wrong?

Share Improve this question asked Jul 12, 2019 at 6:26 eibersjieibersji 1,2164 gold badges31 silver badges54 bronze badges
Add a ment  | 

4 Answers 4

Reset to default 4

Your callback(null,response) will not wait for those two callback functions to finish. You can use Promise and use Promise.all(objs).then(function) to wait for all promises finish and run.

Try wrapping two quotation calls in Promise, then utilise Promise.all to wait for both of them to be pleted, then return the result to the 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);
    })
};

Wele to World's Javascript world - Callback hell.

We have some options for your case: Callback hell, async lib, Promise, async/await...

Callback hell: Call a async function in a callback

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 lib: async You can use waterfall function to do actions in order, and parallel if order is not matter.

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

You could also try using util.promisify and the async / await syntax.

For example:

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

We can also do something similar, but without async / await:

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));
};
发布评论

评论列表(0)

  1. 暂无评论