异步操作会导致结果不一致

时间:2014-11-30 14:59:54

标签: node.js asynchronous callback

我是nodejs的新手并且正在努力应对其异步行为。 我想要做的是编写REST API,它将消耗其他API并依赖于这些结果。 我尝试做的是将调用封装到函数[1]并收集数据并用它做一些事情[2]然后再发送给我的API调用者。 问题是,当我收集[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}

});

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

1 个答案:

答案 0 :(得分:1)

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

使用async

解决此问题的示例
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);
    });

});

什么函数并行做,来自doc

  

并行运行tasks函数数组,无需等到   上一个功能已经完成。如果任何功能通过   对其回调错误,主要回调立即调用   错误的价值。任务完成后,结果如下   作为数组传递给最终回调。