首页 > 解决方案 > 如何在 nodejs 中使用异步瀑布进行 API 调用

问题描述

在我的应用程序中,我必须逐步执行一系列 API 调用。我尝试使用异步瀑布选项来实现这一点。但是在获得第一个 API 的响应之前,第二个函数正在执行,并且第二个函数也发生了同样的事情。那是在得到响应之前,最终结果是 send 。如果我尝试执行 API 调用以外的其他任务,则瀑布操作正常进行。以下是我尝试过的代码。出于测试目的,从两个函数(myFirstFunction、mySecondFunction)调用相同的 API。

const async = require('async');
router.get('/', (req, res) => {
    async.waterfall([
        myFirstFunction,
        mySecondFunction,
    ],
        function (err, result) {
            if (err) {
                console.log("Error-->" + JSON.stringify(err));
                res.status(400).json(err).end();
            } else {
                console.log(" Result -->" + JSON.stringify(result));
                res.status(200).json("Success").end();
            }
        });

});

const myFirstFunction = (callback) => {
    console.log(" ------- myFirstFunction ");
    const vehList = callVehicle();
    console.log("First Function -->" + JSON.stringify(vehList));
    callback(null, vehList);
}
const mySecondFunction = (vehList, callback) => {
    console.log("-------- mySecondFunction");
    const vehList1 = callVehicle();
    const vehList2 = {
        "1": vehList,
        "2": vehList1
    }
    console.log("Second Function -->" + JSON.stringify(vehList2));
    callback(null, vehList2);
}

const callVehicle = () => {
    var options = {
        method: "GET",
        json: true,
        strictSSL: false,
        url: `http://localhost:8080/vehicle/make`
    };
    request(options, function(error, response, body) {
        if (body){
          console.log("Success REST Response: ", JSON.stringify(body));
          return body;
        } else {
          console.log("Error : ", JSON.stringify(error));
          return {"Error": "error"};
        }
      });
}

获得的输出

F:\workSpace_Node\SampleApp>node app.js
server running at 9086
 ------- myFirstFunction
First Function -->undefined
-------- mySecondFunction
Second Function -->{}
 Result -->{}
Success REST Response:  {"vehicleList":[{"make":"Audi","model":"A3","vin":"QVFCFQT7894563214"},{"make":"Audi","model":"A4","vin":"ASECFQT7894563214"},{"make":"Audi","model":"Q7"},{"make":"Audi","model":"Q5","vin":"QWECFQT7894993214"}]}
Success REST Response:  {"vehicleList":[{"make":"Audi","model":"A3","vin":"QVFCFQT7894563214"},{"make":"Audi","model":"A4","vin":"ASECFQT7894563214"},{"make":"Audi","model":"Q7"},{"make":"Audi","model":"Q5","vin":"QWECFQT7894993214"}]}

如何使用 async.waterfall 来实现这一点,或者有没有更好的方法来满足这个要求。

标签: node.jsasynchronouswaterfall

解决方案


对我来说使用 Promises 和异步函数的最佳方式。

但是如果你想在没有承诺的情况下做到这一点,我认为你所有的异步代码都应该得到一个回调参数。

但是您没有回调参数,因此在收到响应callVehicle时无法通知父函数。call Vehicle

const myFirstFunction = (callback) => {
    callVehicle(callback);
}
const mySecondFunction = (vehList, callback) => {
    const vehList1 = callVehicle((err, res) => callback (err, {
    1: vehList,
     2: res
  }));
}
// We add callback that should be called when we have a result of the api request
const callVehicle = (callback) => {
    var options = {
        method: "GET",
        json: true,
        strictSSL: false,
        url: `http://localhost:8080/vehicle/make`
    };
    request(options, function(error, response, body) {
        if (!error && body){
          console.log("Success REST Response: ", JSON.stringify(body));
          callback(null, body)
        } else {
          console.log("Error : ", JSON.stringify(error));
          callback({ Error: error }, null)
      });
}

承诺:

const get = (options) => new Promise(
  (resolve, reject) => request(
    {method: 'GET', ...options},
     (err, response, body)=> err ? reject(err) : resolve(body)
  )
)

const callVehicle = () => get({
  json: true,
  strictSSL: false,
  url: `http://localhost:8080/vehicle/make`
})

router.get('/', async (req, res) => {
  try {
    const firstVehicle = await callVehicle()
    const secondVehicle = await callVehicle()
    res.status(200).json("Success").end();
  } (error) {
    res.status(400).json(error).end();
  }
});

推荐阅读