Массив promise'в (vow)
Доброго времени суток.
Начал писать парсер html, столкнулся с проблемой ожидания promise'ов. Использую vow. Есть некий код: var promises = [], arr = []; var parseUrl = function (i, url) { promises[i] = vow.defer(); request({uri:url,method:'GET',encoding:'binary'}, function (err, res, body) { var $=cheerio.load( iconv.encode( iconv.decode( new Buffer(body,'binary'), 'win1251'), 'utf8') ); arr[i] = $(some_selector).text(); console.log(arr[i]); return promises[i].resolve(); }); } var someFunc = (function () { var urls = {0:'some_url'}; for(i in urls) { parseUrl(i, urls[i]); } vow.all(promises).spread(function () { for(i in urls) { console.log(arr[i]); } }); })(); Собственно проблема в том, vow.all не ждёт ответа, а выводит "undefined", а потом выводится console.log с нужной информацией из функции parseUrl. Если promises объявить как переменную, то проблема решается, но ссылок будет неопределенное кол-во, и соответственно такой вариант мне не подходит. В документации описано только: var defer1 = vow.defer(), defer2 = vow.defer(); vow.all([defer1.promise(), defer2.promise(), 3]) .then(function(value) { // value is "[1, 2, 3]" here }); defer1.resolve(1); defer2.resolve(2); что мне не подходит из-за неопределенного кол-ва promise'ов. Есть ли решение данной проблемы, или стоит присмотреться к другим promise модулям (Q/When)? ps: io.js поставил 4 часа назад, заранее извиняюсь за возможно очевидные косяки =) |
Цитата:
https://www.npmjs.com/package/htmlparser2 Цитата:
https://developer.mozilla.org/en-US/...bjects/Promise http://www.2ality.com/2014/10/es6-promises-api.html Цитата:
let promises = new Map(); promises.set(1, new Promise()); https://developer.mozilla.org/en-US/...al_Objects/Map Цитата:
|
Цитата:
let urls = new Map([ [0, "some_url"] ]); lets urls = ["some_url"]; Цитата:
for (let [i, url] of urls) { parseUrl(i, url); } |
А вообще, как-то так делается:
function parseUrl(url) { return new Promise((resolve, reject) => { request.get(url, (err, res, body) => { if (err) { reject(err); return; } resolve(body); }) }); } let urls = ["http://javascript.ru", "http://habrahabr.ru"]; Promise.all( urls.map((url) => parseUrl(url)) ).then((body) => { console.log(`Response arrived: ${body}`); }).catch((err) => { console.log(`Error occured: ${err}`); }); |
Цитата:
Видимо неправильно выразился, я пишу не сам парсер, а некую утилиту, которая парсит(с помощью готового модуля), и потом обрабатывает результат. Цитата:
Цитата:
Цитата:
Цитата:
Про глобал в курсе, тут большая часть кода, это компиляция из нескольких примеров под node.js, переписанная под новый синтаксис vow. Поэтому пока не разобрался, решил синтаксис не трогать, обратившись к принципу "работает - не трогай". Попробовал последний пример, вываливается с Unexpected token для '=>' Может какой-нибудь модуль подключить нужно? |
Цитата:
Цитата:
Цитата:
Либо запускай ио с флагом --harmony_arrow_functions, либо пропускай код через babel, либо перепеши на обычные функции. |
переписал на обычные функции, работает, получилось нечто такое:
function parseUrl(url) { return new Promise(function(resolve, reject) { request.get(url, function(err, res, body) { if (err) { reject(err); return; } var $=cheerio.load( iconv.encode( iconv.decode( new Buffer(body,'binary'), 'win1251'), 'utf8') ); var obj = { h1 : $(some_selector).text(), last : $(some_selector).text() } resolve(obj); }) }); } var urls = ["some_url", "some_url", "some_url"]; Promise.all( urls.map(parseUrl) ).then(function(obj) { console.log(obj); }).catch(function(err) { console.log('Error occured: '+err); }); Правильно ли я понимаю что возвращаются promise в том же порядке что вызываются, и не получится что вернулся сначала второй, потом первый, т.к. по второй ссылке сервер ответил быстрее? |
Цитата:
|
Цитата:
urls.map(function(url){return parseUrl(url)}) |
Цитата:
urls.map(function(url){return parseUrl(url)}) да, я сначала так и переписал, когда пытался ещё i в функцию передать, но потом когда понял что возвращаются объекты по очереди, и второй аргумент не нужен немного сократил =) если что, пример увидел здесь Большое спасибо, теперь всё работает как нужно! =) ps может ещё подскажите в сторону какого модуля можно погуглить, чтобы сделать очередь из запросов (чтобы сервер с 503 ошибкой не выкидывал)? |
Часовой пояс GMT +3, время: 04:44. |