node.js - 如何在 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 来实现这一点,或者有没有更好的方法来满足这个要求。
解决方案
对我来说使用 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();
}
});
推荐阅读
- c++ - 在cpp中获取图像的公制尺寸
- elasticsearch - 对两个字段进行聚合会为其中一个返回空值
- python-3.x - 基于单独数据帧上的 2 列不存在 Python 返回
- reactjs - 单击另一个组件中的按钮时如何显示/隐藏 React 组件?
- java - 当我加载我的我的世界时,我收到错误 java.lang.NullPointerExeption 我该如何解决这个问题?
- node.js - NodeJs / Express:避免对许多文件进行顺序处理
- ajax - 加载更多相同类别的帖子 - WordPress + Ajax + Timber
- excel - Excel UDF 被调用两次,每次返回不同的值
- vba - 链接到未绑定文本框的重新查询/空子表单
- python-3.x - 如何使用 Python SDK 从 Azure 数据湖中删除文件?