Цикл возврата HTTP-запросов javascript с обещаниями

У меня есть функция, которая перебирает массив URL-адресов для анализа с помощью запросов. Однако, поскольку мне нужен цикл for, охватывающий запрос, я не знаю, как вернуть массив. Если у меня есть возврат обещаний вне запроса, я теряю отправленные элементы, поскольку запросы - это функция. Я использую bluebird для обещаний.

Вот что у меня есть на данный момент:

function getSrc (urls, fileList) {
    var path = "#section > a[href]";
    var container = [];
    var i = 0;

    return new Promise(function(fullfill, reject) {
        for (; i < urls.length; i++ ) {         
            request(urls[i], function (err, resp, page) {
                if (!err && resp.statusCode == 200) {
                    var $ = cheerio.load(page); // load the page
                    fileList.push($(path).attr("src"));
                    container.push(fileList);
                    fullfill(container);
                } // end error and status code
                else {reject('error');}
            }); // end request    
        } // end FOR loop
        // fullfill(container); // how can i get this to wait for requests to fill array?
    });
}

person user147910    schedule 11.08.2015    source источник


Ответы (1)


Вы не можете использовать цикл for таким образом, потому что все ваши запросы будут выполняться одновременно, и первый, который завершится, вызовет ваш обратный вызов fullfill (sic).

Общепринятый способ сделать это - использовать Promise.map() для перебора ваших URL-адресов. Что-то вроде:

var request = Promise.promisifyAll(require('request'));

Promise.map(urls,request.get).catch(function(err){
    // oops, one of the requests failed!
  }).then(function(results){
    // do something with the array of all results, one for each url.
  });
person Rob Raisch    schedule 11.08.2015