【问题标题】:async.js Ordering of functionsasync.js 函数排序
【发布时间】:2017-12-12 14:01:25
【问题描述】:

所以我无法让一个 javascript 函数在下一个函数开始之前完成。我花了很多时间尝试使用其他 stackoverflow 帖子中描述的回调方法。我可以获得使用超时工作但无法使用我的 API 请求的简单示例。我偶然发现了async.js,并认为使用async.series 让我的两个函数一个接一个地执行可能是个好主意。所以我尝试了这种方法,但是我似乎仍然遇到第一个函数需要更长的时间来执行的问题(这很好)但是执行过程会移过这个函数而不是等待它结束。我觉得我有某种误解,因为我尝试了几种方法但无济于事。

奇怪的是,当运行server.js 时,它进入了第一个函数,然后在请求完成之前就离开了async.series() 函数。当我在tokenReq() 内部打印时,我可以看到请求成功,因为成功返回了令牌代码,但是随着执行的继续,这种情况发生得很晚。输出如下所示。

server.js:

var access_code;
async.series([
    function() {
        access_code = queries.data.tokenReq(code);
        console.log("Finished inside function 1");
    },
    function() {
        console.log("\n Starting function 2 \n");

        if (access_code === "error") {
            res.json("An error has occured");
        } else {
            var response = queries.data.messagesReq(access_code);
            res.json(response);
        }
    }
],
function(err, access_code) {
});

console.log("Outside");

queries.js:

tokenReq: function(code) {
    var tokenUrl = "https://login.microsoftonline.com/common/oauth2/v2.0/token";
    var form = {
        code: code,
        client_id: "__ID__",
        redirect_uri: "__Site__/",
        grant_type: "authorization_code",
        client_secret: "__Secret__",
    };


    var formData = querystring.stringify(form);
    var contentLength = formData.length;

    request({
            headers: {
            'Content-Length': contentLength,
            'Content-Type': 'application/x-www-form-urlencoded'
            },
            uri: tokenUrl,
            body: formData,
            method: 'POST'
        }, function (error, response, body) {

        if (error != "null") {
            var access_token = JSON.parse(body).access_token;
            console.log("\n INSIDE FUNCTION REQUEST, Token: " + access_token + " \n");
            return access_token;

        } else {
            console.log('error:', error); // Print the error if one occurred
            console.log('statusCode:', response && response.statusCode); // Print the response status code if a response was received
            //   console.log('body:', body); // Print the HTML for the Google homepage.
            return "error";
        }
    });
},

输出:

Finished inside function 1
Outside

INSIDE FUNCTION REQUEST, Token: 8Swhd.......

【问题讨论】:

    标签: javascript node.js async.js


    【解决方案1】:

    你在这里错过了一个重点。由于 node.js 是异步的,因此不应该知道函数何时完成执行。这就是我们指定回调的原因,以便调用函数在完成执行时知道要调用谁。一旦有了带有回调的函数,就可以使用 async 模块强制执行系列/并行/瀑布行为。

    tokenReq: function(code, cb) {
        var tokenUrl = "https://login.microsoftonline.com/common/oauth2/v2.0/token";
        var form = {
            code: code,
            client_id: "__ID__",
            redirect_uri: "__Site__/",
            grant_type: "authorization_code",
            client_secret: "__Secret__",
        };
    
    
        var formData = querystring.stringify(form);
        var contentLength = formData.length;
    
        request({
            headers: {
                'Content-Length': contentLength,
                'Content-Type': 'application/x-www-form-urlencoded'
            },
            uri: tokenUrl,
            body: formData,
            method: 'POST'
        }, function (error, response, body) {
    
            if (error != "null") {
                var access_token = JSON.parse(body).access_token;
                console.log("\n INSIDE FUNCTION REQUEST, Token: " + access_token + " \n");
                return cb(null, access_token);
    
            } else {
                console.log('error:', error); // Print the error if one occurred
                console.log('statusCode:', response && response.statusCode); // Print the response status code if a response was received
                //   console.log('body:', body); // Print the HTML for the Google homepage.
                return cb(new Error("whatever"));
            }
        });
    },
    

    现在,您可以在server.js 中使用回调

    var access_code;
    async.series([
        function(cb) {
            return queries.data.tokenReq(code, cb);
        },
        function(access_code, cb) {
            console.log("\n Starting function 2 \n");
    
            if (access_code === "error") {
                res.json("An error has occured");
            } else {
                var response = queries.data.messagesReq(access_code);
                res.json(response);
            }
            // do whatever you want after this
            return cb();
        }
    ],
    function(err, access_code) {
        if (err) {
            console.log(err);
        }
        // wrap your logic around a function and call the correspoding callback here
    });
    

    【讨论】:

      猜你喜欢
      • 2020-06-23
      • 2014-03-11
      • 2017-03-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-09
      • 2017-03-25
      • 1970-01-01
      相关资源
      最近更新 更多