Как стать автором
Поиск
Написать публикацию
Обновить

Комментарии 25

Вы сделали обычную очередь.

Не вижу преобразования асинхронного кода в синхронный. Это вообще невозможно в общем случае.
Ну как же, есть цикл запуска асинхронных функций, которые были запущены последовательно. Возможно я не совсем верно отразил это в заголовке.
Спасибо за статью.
А можно было данную проблему решить с помощью библиотеки async(http://caolan.github.io/async/)?
Можно, но я предпочитаю не использовать сторонние библиотеки, если есть возможность решить задачу стандартными средствами.
я предпочитаю не использовать сторонние библиотеки, если есть возможность решить задачу стандартными средствами.

Почему же тогда вы взяли q (где промисы не по es6), а не стандартные промисы?

Можно и стандарт, в примере привел кусок рабочего кода. И опять же, вы придираетесь :)

Просто для разъяснения: рабочий код — не значит хороший код.
Кроме функциональности, в коде имеет значение чтобы он был легко понимаем, легко поддерживался, имел минимум скрытых эффектов и багов, нестандартных решений которые потом могут аукнуться если код нужно будет кому-нибудь изменить или надстроить.
Стандарты и библиотеки как раз для этого и создаются.

Наверное, пройдет еще лет 40, и люди начнут потихоньку использовать современный Javascript, но не везде и не полностью, ведь все еще нужно поддерживать IE5.5.

Автор, у вас вместо кода дикое, мерзкое, нечитаемое месиво вместо кода.

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 в несколько раз быстрее нативных промисов, поэтому имеет смысл его использовать даже там, где промисы поддерживаются нативно.

Да, bluebird быстрее, но async/await — это очень медленно (в случае regenerator'а), чуть менее медленно в случае генераторов (если в ноде). Есть ли смысл тогда сочетать bluebird с async/await?

Ну использование regenerator в принципе обоснованно только для очень старых платформ, которые не поддерживают генераторы, а там уже о скорости никто не думает — да и нативных промисов там в таком случае тоже отродясь не было, поэтому сравнивать не с чем. Для окружений возрастом хотя бы в пару лет уже имеет смысл использовать исключительно генераторы.


А о том, что генераторы медленнее промисов — у вас есть какие-то материалы по теме? Быстрый гуглеж показал результаты противоположные вашему заявлению, но я их не верифицировал.

Материалов, увы, нет. Наверное, все ж, сложившееся (само собой, стереотипное) мнение. А как там дела у V8 в бенчах вообще трудно смотреть, он, зараза, оптимизирует все, попробуй правильный бенч напиши еще.
Кстати, залез сейчас посмотрел поддержку генераторов — остался приятно удивлен. Но, увы, бизнес в моем случае требует мобайл (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)

Минусующие поясните в чем тут проблема. С async/await подход конечно лучше, но чейн промисов вроде нормальная практика? А Q здесь можно заменить любой другой реализацией.

На мой взгляд — вполне нормальная практика. Плюс, большинство библиотек так или иначе предоставляют утилитарный метод для этого, куда можно просто скормить массив промисов.

НЛО прилетело и опубликовало эту надпись здесь
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации