如何在异步函数中等待请求方法

时间:2015-10-06 18:25:56

标签: javascript node.js asynchronous


我尝试执行多个迭代函数,无法克服node.js异步工作类型。

async.waterfall([
    function (callback) {
       // function gets amount of pages
    },
    function (amountOfPages, callback) {
        //addes a url to each page
    },
    function (links, callback) {
        //Now i need to go over each link , and extract info from that page 
        var tradelinks = [];
        async.each(links, function (link, callback){

            console.log("In loop : "+ link) // Until this part its doing all right , then it hangs on the request 

            request(link , function (error, response, body) {
                //extract from page... 
            })
            callback()
        })
        callback(null, tradelinks);
    }
], function (err, result) {
    console.log("Done")
    console.log(result)
});

基本上它以正确的顺序执行前两个函数,然后它遍布链接并且不等待请求函数执行,所以我在结果中得到一个空白数组并且done标志只有在那之后,它才会打印从页面中提取的数据。

我的输出看起来像这样

Function 1 done
Function 2 done
In the async.each loop // for how many links there are
Done
[] //only after this point the data extracted from page appears
extracted data // for how many links there are 

我对这种编程很新,并且真的不知道如何从这里开始。我知道这可以通过承诺或类似的东西来完成,但我似乎无法让它工作。

3 个答案:

答案 0 :(得分:1)

您的问题似乎是您在异步流之外发布了callback(null, tradelinks)。您需要在.each的回调中进行,它会通知每次迭代都已完成:

async.each(links, function() { stuff here }, function() {
  callback(null, tradelinks);
});

答案 1 :(得分:0)

问题是请求也是异步的。这是你在做什么:

    async.each(links, function (link, callback){

        console.log("In loop : "+ link) 

        request(link , function (error, response, body) {
            //I am async too. And I just fire off and async.each
            //processes the next item in the array, fires me off again,
            //and never waits for me to complete. You really need to 
            //put async.each's callback inside me and all will be well.
            //Also, change async.each's callback to cb because while
            //Javascript's functional scope makes it ok, it's still
            //confusing to read.
        })
        callback()
    })

所以,新代码应该这样做,你会没事的。

    async.each(links, function (link, cb){

        console.log("In loop : "+ link)

        request(link , function (error, response, body) {
            //do stuff synchronously
            cb() 
        })

    })

答案 2 :(得分:-1)

异步调用在堆栈中使用回调函数。看这个:

function init(){
    /* 1- stack */
    async("any data", function(data){
        first(data);
    });
}

function async(data, callback){
    /*
    .
    . Code async
    .
    */
    callback(data);
}

function first(data){
    /* 2- stack */
    async("any data", function(data){
        second(data);
    });
}

function second(data, callback){
    /* 3- stack */
    async("any data", function(data){
        third(data);
    });
}

function third(data){
    console.log(data);
}