异步操作会导致不可靠的结果



我是nodejs的新手,并且正在为它的异步行为而苦苦挣扎。我想做的是编写一个 REST API,它将使用其他 API 并依赖于这些结果。我试图做的是将调用封装到函数 [1] 中,并在将数据发送给 API 的调用方之前收集数据并对其进行处理 [2]。问题是,在我收集 [2] 数据时,callApiX函数 [1] 仍在运行,最终将产生undefined值。此外,我需要调用某些函数超过 1 次并比较值。

[1] 调用 API 的函数:

function callApi1() {
    var result =
    {
        "code": "",
        "name": "",
        "lat": 0,
        "lng": 0
    };
    var request = require("request");
    var url = "someurl";
    request({
        url: url,
        json: true
    }, function (error, response, body) {
        if (!error && response.statusCode === 200) {
            // fill result
            result.code = body.code; // etc.
            // the correct result is being displayed
            console.log(result);
            return result;
        }
    })
}
function callApi2() // ...

[2] 从函数中获取数据并添加到请求

var express    = require('express');
var router = express.Router();
app.route('/api')
.get(function(req, res) {
    // array for results
    var results = [];
    // all this data is going to be undefined, since the callApiX functions [1] are still running
    results += callApi1();
    results += callApi2();
    results += callApi3();
    // do something with the data collected in results before being sent back to the caller of my API
    res.json(results); // output: {undefinedundefinedundefined}
});

我怎么可能解决这个问题?

有几种方法(嵌套回调,承诺......)如何实现您想要的,您可以在下面看到其中一种

示例如何使用异步解决此问题,

npm install async

.JS:

var async = require('async');    
function callApi1 (callback) {
    var result =
    {
        "code": "",
        "name": "",
        "lat": 0,
        "lng": 0
    };
    var request = require("request");
    var url     = "someurl";
    request({
        url: url,
        json: true
    }, function (error, response, body) {
        if (!error && response.statusCode === 200) {
            result.code = body.code;
            return callback(null, result)
        } else {
            callback(error);
        }
    })
}
function callApi2() // ...

var express    = require('express');
var router = express.Router();
app.route('/api')
.get(function(req, res) {
    async.parallel([
        function(callback){
            callApi1(callback);
        },
        function(callback) {
            callApi2(callback);
        },
        function(callback){
            callApi3(callback);
        }
    ], function (err, results) {
        res.json(results);
    });
});

函数并行做什么,来自文档

并行运行任务函数数组,无需等待 上一个函数已完成。如果任何函数传递 回调错误,主回调立即调用 错误的值。任务完成后,结果是 作为数组传递给最终回调。

最新更新