2015-10-18 2 views
3

У меня странная проблема, когда я нажимаю свой результат в моем массиве, результат не находится в правильном положении в моем массиве (например, результат вместо того, чтобы быть у индекса 1 при индексе 3), и когда я повторно запускаю результаты моего модуля, изменяя позицию случайным образом в массиве.Array не соответствует указанному заказу

var cote = function(links, callback) { 

    var http = require('http'); 
    var bl = require('bl'); 

    var coteArgus = []; 

    for (i = 0; i < links.length; i ++) { 
    http.get('http://www.website.com/' + links[i], function(response) { 

     response.pipe(bl(function(err, data) { 
     if (err) { 
     callback(err + " erreur"); 
     return; 
     } 

     var data = data.toString() 

     newcoteArgus = data.substring(data.indexOf('<div class="tx12">') + 85, data.indexOf(';</span>') - 5); 
     myresult.push(newcoteArgus); 

     callback(myresult); 
     })); 
    }); 
    } 
}; 

exports.cote = cote; 
+0

кажется, это зависит от работы '$ http.get' и когда он получает ответ от сервера для каждого запроса – Grundy

+0

' Array.push() 'всегда добавляет к конец массива. Поэтому, если массив не в том порядке, который вы ожидаете, я бы посмотрел на данные, которые вы нажимаете на массив ... это выражение, которое вы используете, где вы вызываете 'substring()' и 'indexOf() 'выглядит как возможный преступник ... Осмотрите значение этого выражения в отладчике или зарегистрируйте его на консоли. –

ответ

4

Проблема заключается в том, что, хотя for является синхронным http.get и операция pipe не является (I/O является асинхронным в nodejs), так что порядок массива зависит от того, запроса и труба заканчивается первой который неизвестен.

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

+0

Как я могу использовать мой цикл для выполнения асинхронных операций? Я не знаю, как это сделать. – Peter

0

Я думаю, что это может быть сделано в правильном порядке, используя async map

Здесь образец с картой и с помощью request module. более

// There's no need to make requires inside the function, 
// is better just one time outside the function. 
var request = require("request"); 
var async = require("async"); 

var cote = function(links, callback) { 

    var coteArgus = []; 

    async.map(links, function(link, nextLink) { 

    request("http://www.website.com/" + link, function(err, response, body) { 
     if (err) { 
     // if error so, send to line 28 with a error, exit from loop. 
     return nextLink(err); 
     } 

     var newcoteArgus = body.substring(
     body.indexOf("<div class='tx12'>") + 85, 
     body.indexOf(";</span>") - 5 
     ); 
     // pass to next link, and add newcoteArgus to the final result 
     nextLink(null, newcoteArgus); 
    }); 
    }, 
    function(err, results) { 

    // if there's some errors, so call with error 
    if(err) return callback(err); 

    // there's no errors so get results as second arg 
    callback(null, results); 
    }); 

}; 

exports.cote = cote; 

Одна вещь, я не уверен, на самом деле то, что вы делаете в той части, где искать содержимое HTML в ответах but there's a really good library to work with JQuery selectors from server side может быть может быть полезно для вас.

Вот как вы должны вызвать функцию

// Call function sample. 
var thelinks = ["features", "how-it-works"]; 

cote(thelinks, function(err, data) { 

    if(err) return console.log("Error: ", err); 
    console.log("data --> ", data); 

}); 
+0

Не обязательно быть 'mapSeries' или' everySeries'. __map__ и __each__ будут работать отлично. Если вы запускаете его последовательно, это означает, что каждый запрос будет ждать завершения предыдущего. но порядок «результата» будет таким же, как и «map», а «mapSeries» будет последним значительно медленнее. – Maroshii

+0

Ваше изображение не работает, оно возвращает значение null, а исследование для html не работает, а http.get() - лучше. – Peter

+0

@Maroshii Извините, если я ошибаюсь, но я думаю, что если вы не будете ждать в каждом цикле, чтобы запрос был завершен, вы не можете гарантировать порядок массива результатов, поэтому, если вы используете каждую или карту, массив будет продолжать заполнять Любой заказ. взгляните на это описание https://github.com/caolan/async#collections-1 - прочитайте примечание, так как эта функция применяет итератор к каждому элементу параллельно, нет гарантии, что функции итератора будут завершены в порядке , –

Смежные вопросы