2013-10-24 4 views
0

У меня есть небольшая проблема с использованием nodejs с Async lib.NodeJS: модуль и порядок Async

Вот и проблема: я пытаюсь получить ссылки с веб-сайта и отображать их в массиве.
Проблема в том, что когда я запускаю скрипт, он сначала отображает вторую функцию, а затем первую функцию.
Почему? :/

var request = require("request"); 
var cheerio = require("cheerio"); 
var async = require("async"); 
var homepage = "http://xxx"; 
var start = []; 

async.series([ 

function(callback){ 
    //Request to website 
    var myVisit = request(homepage,function(err,resp,body){ 
     if(err) throw err 

      $ = cheerio.load(body); 
    ////Get all the links in the list 
      $('aside ul li').each(function(){ 
       start.push($(this).find('a').attr('href')); 
      }); 
      console.log(start); 
    }); 

    callback(null, myVisit); 
}, 
    /// Dummy function 
function(callback){ 
    var display = console.log("Blabla"); 
    callback(null,display); 
} 


]); 

///Outputs 'Blabla' and then the links array 

ответ

0

Вы вызываете функцию обратного вызова async в неправильном месте первой функции. Вызов функции запроса не блокируется, и код переходит к следующей строке. Для серии async, как только вызывается обратный вызов async, он покидает функцию и начинает выполнение следующей функции.

Возможное решение будет положить callback (null, myVisit) внутри обратного вызова запроса. Вы ждете, когда функция запроса вернет результат. Получите все ссылки, а затем вызовите обратный вызов async

+0

Это не проблема. Объявление 'request (..)' и передача его ссылки на 'callback (null, myVisit);' это правильный способ сделать это. То, о чем @ user2914878 не думал, является отложенной и отложенной формой, в которой 'myVisit' будет сообщать о своих результатах (с помощью' console.log (start); '). Мой ответ объясняет это более подробно. – Saran

+0

Я думал, что он хочет обеспечить выполнение первой функции, а req (...) дает ее результат перед вызовом следующей функции. Поэтому я предложил это решение, которое блокирует запрос. – ankit042

+0

На самом деле, я хочу, чтобы первая функция выполнялась сначала, а затем переходила ко второй функции. @ ankit042 вы решили работать. Я положил обратный вызов в конце запроса. – user2914878

0

Это связано с тем, что, хотя async.series гарантирует заказ, он будет вызывать задачи/функции, это не значит, что он может гарантировать порядок результатов, если результат был произведен другим функция асинхронных вызовов.

Если вы использовали его, как это:

async.series([ 
    function(callback){ 
     // do some stuff ... 
     console.log('one'); 
    }, 
    function(callback){ 
     console.log('two'); 
    } 
]); 

Вы получите это:

one 
two 

Но указания асинхр request(...) означает, что он будет log только после того, как что функция заканчивается.

Вы можете проверить это следующим образом:

var request = require("request"); 
var cheerio = require("cheerio"); 
var async = require("async"); 
var homepage = "http://xxx"; 
var start = []; 

async.series([ 

function(callback){ 
    console.log('1st async task'); 
    //Request to website 
    var myVisit = request(homepage,function(err,resp,body){ 
     if(err) throw err 

      $ = cheerio.load(body); 
    ////Get all the links in the list 
      $('aside ul li').each(function(){ 
       start.push($(this).find('a').attr('href')); 
      }); 
      console.log(start); 
    }); 

    callback(null, myVisit); 
}, 
    /// Dummy function 
function(callback){ 
    console.log('2nd async task'); 
    var display = console.log("Blabla"); 
    callback(null,display); 
} 


]); 

Теперь вы должны получить такой результат:

1st async task 
2nd async task 
Blabla 
[links] 
Смежные вопросы