Comments 25
Не вижу преобразования асинхронного кода в синхронный. Это вообще невозможно в общем случае.
А можно было данную проблему решить с помощью библиотеки async(http://caolan.github.io/async/)?
я предпочитаю не использовать сторонние библиотеки, если есть возможность решить задачу стандартными средствами.
Почему же тогда вы взяли q (где промисы не по es6), а не стандартные промисы?
Просто для разъяснения: рабочий код — не значит хороший код.
Кроме функциональности, в коде имеет значение чтобы он был легко понимаем, легко поддерживался, имел минимум скрытых эффектов и багов, нестандартных решений которые потом могут аукнуться если код нужно будет кому-нибудь изменить или надстроить.
Стандарты и библиотеки как раз для этого и создаются.
Автор, у вас вместо кода дикое, мерзкое, нечитаемое месиво вместо кода.
import Promise from 'bluebird';
async function process(item) {
console.log(`start call for ${item}`);
await Promise.delay(1000);
console.log(`end call for ${item}`);
}
async function main() {
const items = [1, 2, 3, 4, 5];
for (let item of items) {
await process(item);
}
}
main().then(() => {
console.log(`done`);
});
Правильно — вы планировали статью "ах, какой я молодец", а получилась статья "как написать говно на JS и не подать виду".
Вы вместо простого и элегантного подхода выбрали самый сложный и неправильный — вместо new Promise((resolve, reject) => { ... })
, как рекомендует спецификация, вы используете defer, который мало того, что тянет за собой огромный, медленный Q, еще и стандарту не соответствует.
Нагородили итератор и генератор поверх массива, вместо for (let x of y) { ... }
, который нода, между прочим, поддерживает уже очень давно, даже без дополнительных флагов. Сделали мешанину анонимных функций в теле main. Зачем?!.. Зачем там замыкание, вы объясните? На что оно замыкается? Нахрена ему это делать прямо в main при каждом вызове?
Родина вам async/await дала — пиши. Не хочу, хочу setTimeout. И это программисты? Какая может быть уважительная причина их не использовать?
Импортнул из двух соображений. Первое — готовая реализация Promise.delay()
:
function delay(timeout) {
return new Promise((resolve, reject) => setTimeout(resolve, timeout));
}
Второе — Bluebird в несколько раз быстрее нативных промисов, поэтому имеет смысл его использовать даже там, где промисы поддерживаются нативно.
Ну использование regenerator в принципе обоснованно только для очень старых платформ, которые не поддерживают генераторы, а там уже о скорости никто не думает — да и нативных промисов там в таком случае тоже отродясь не было, поэтому сравнивать не с чем. Для окружений возрастом хотя бы в пару лет уже имеет смысл использовать исключительно генераторы.
А о том, что генераторы медленнее промисов — у вас есть какие-то материалы по теме? Быстрый гуглеж показал результаты противоположные вашему заявлению, но я их не верифицировал.
Кстати, залез сейчас посмотрел поддержку генераторов — остался приятно удивлен. Но, увы, бизнес в моем случае требует мобайл (ios9), так что, все-равно, придется фоллбечить. А мобилки — и так черепахи.
Этот пост стоило написать ради вашего комментария (не сарказм)
Вот так очень просто взяв обычный мерседес, с молотком и напильником мы можем сделать жигуль!
Если надо несколько раз последовательно вызвать асинхронную функцию —
можно их просто chain'ить на результат предыдущей:
const Q = require('q');
var d = Q(1);
for ( var i = 0; i < 5; i++ ) (function(i){
d = d.then(function(){
return somethingThatReturnsPromise(i);
});
})(i)
Асинхронный код в синхронный встроенными средствами