Массив 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 ошибкой не выкидывал)? |
Цитата:
https://developer.mozilla.org/en-US/...ects/Array/map - вот здесь получше будет. Там и предостережение есть. Цитата:
Цитата:
|
Хорошо, ещё раз спасибо =)
|
Цитата:
Не могу понять, как правильно добавить в promise setInterval, когда внутри него асинхронные функции. Следующий .then не дожидается их выполнения. Promise.all наверное не подходит, т.к. данные подгружаются внутри setInterval динамически, объём большой, скорее всего будет переполнение буфера. Но даже как его применить, в данном случае, я не могу понять. |
Извините, разобрался, тупил, resolve закопипастил и забыл удалить.
|
Часовой пояс GMT +3, время: 04:24. |