Pull to refresh

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

UFO just landed and posted this here
Ну, так то, можно еще и промисы не импортить

Импортнул из двух соображений. Первое — готовая реализация 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 здесь можно заменить любой другой реализацией.

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

UFO just landed and posted this here
Sign up to leave a comment.

Articles