【问题标题】:Combine two callbacks into one return将两个回调合并为一个返回
【发布时间】:2019-07-12 15:33:56
【问题描述】:

所以我有这个代码:

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" }]

我做错了什么?

【问题讨论】:

    标签: javascript node.js serverless-framework


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

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

      我们为您的情况提供了一些选项:回调地狱、异步库、承诺、异步/等待...

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

      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】:

        尝试在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);
            })
        };
        

        【讨论】:

          【解决方案4】:

          您也可以尝试使用 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));
          };
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2019-10-08
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-03-26
            • 1970-01-01
            • 1970-01-01
            • 2021-05-01
            相关资源
            最近更新 更多