Async: Обещаю поддержку

Созданный на 13 нояб. 2015  ·  22Комментарии  ·  Источник: caolan/async

Добавьте поддержку обещаний, чтобы можно было смешивать разные задачи:

async.waterfall([
    function (done) {
        // Do something and call done()
        fs.readFile(filepath, done);
    },
    function(content) {
        // Do something and return Promise
        return mongoose.models.file.create({
            name: filepath,
            content: content
        });
    }
], (err) => {
    if (err) {
        console.error(err);
    }
});

Самый полезный комментарий

Я думаю, что так же, как есть async.asyncify, может быть функция async.promisify.

Тогда я могу просто дождаться async.promisify (async.mapLimit (x, 10, mapper))

Все 22 Комментарий

asyncify примет синхронную функцию, которая возвращает Promise, и вызовет обратный вызов для своих разрешенных / отклоненных обработчиков:

async.waterfall([
    function (done) {
        // Do something and call done()
        fs.readFile(filepath, done);
    },
    async.asyncify(function(content) {
        // Do something and return Promise
        return mongoose.models.file.create({
            name: filepath,
            content: content
        });
    })
], (err, model) => {
    if (err) {
        console.error(err);
    }
});

Но эта функция не задокументирована ...

У меня была еще одна мысль - должны ли мы автоматически асинхронизировать функции, возвращающие обещания (или обрабатывать их соответствующим образом?). Что должен делать async при передаче функции ES-what async (которая неявно возвращает обещание)?

например

async.waterfall([
    function (done) {
        // Do something and call done()
        fs.readFile(filepath, done);
    },
    async function(content) {
        return await mongoose.models.file.create({
            name: filepath,
            content: content
        });
    }
], (err, model) => {
    if (err) {
        console.error(err);
    }
});

Лично я считаю, что async должен асинхронизировать обещания по умолчанию. Я пишу некоторые асинхронные функции, которые мне также нужно передать в async.queue, но я не хочу писать это:

import {queue, asyncify} from 'async'

const run = asyncify(async function () {
  await someStuff()
})

const q = async.queue(run)
q.push('asdf')

где я мог бы писать это

import {queue} from 'async'

async function run () {
  await someStuff()
}

const q = async.queue(run)
q.push('asdf')

Добавлены документы для asyncify . Собираюсь оставить это открытым для автоматического асинхронного поведения.

Об этом я экспериментировал с использованием той же кодовой базы и интерфейса Promise для методов, которые используют обратный вызов в качестве последнего параметра. проверь это !

async.waterfall([
  function (callback) {
    callback(null, 'one', 'two')
  },
  function (arg1, arg2, callback) {
    // arg1 now equals 'one' and arg2 now equals 'two'
    callback(null, 'three')
  },
  function (arg1, callback) {
    // arg1 now equals 'three'
    callback(null, 'done')
  }
]).then(function (value) {
  console.log(value === 'done')
})

что ты думаешь об этом? Думаю, адаптировать библиотеку будет несложно. Посмотрите, например, как работает полученный дескриптор библиотеки cb и обещание .

Очень интересно. Если Async правильно обрабатывает функции, возвращающие обещания, то он также может довольно легко принимать обещанные функции Async. Это сработает:

async.parallel([
  async.waterfall([
    asyncFn1,
    function (result1, next) {
      //...
    }
    asyncFn2,
    //...
  ]), // no callback!
  async.each(arr, function (item, cb) {
    //...
  })
  otherAsyncFn
], done)

Было бы намного проще комбинировать функции Async.

Проблема сегодня в том, что обратные вызовы необязательны. Если оставить последний аргумент, задача все равно будет выполнена. Я бы хотел сделать так, чтобы функции Async автоматически каррировались - если вы откажетесь от обратного вызова, он частично применит функцию, и все, что вам нужно сделать, это вызвать ее с помощью обратного вызова. Но поскольку у многих методов есть необязательные параметры, и мы движемся к опциональным обратным вызовам по всем направлениям, вы действительно не можете этого сделать. Наши методы являются вариативными, и вы не можете каррировать вариативные функции.

Однако, если оставить последний обратный вызов для метода, он вернет Promise, и если Async настроен для обработки функций, которые возвращают обещания, это интересная комбинация. Одна из основных проблем заключается в том, что Async придется интегрировать с библиотекой обещаний - с какой? Мы полагаемся на global.Promise , заставляя старые движки выполнять полифилы, или мы используем что-то вроде Bluebird? Кроме того, Async является своего рода заявлением против обещаний - функций высшего порядка для функций, принимающих обратный вызов, а не принятия парадигмы Futures. Я за совместимость с Promises, но думаю, что возвращение обещаний Async немного выходит за рамки его философии дизайна.

@aearly

Я чувствую, что Promises - это рабочий процесс, согласованный с последними версиями узлов (> = 4). В этих версиях доступны обещания, поэтому мое видение заключается в использовании рабочего процесса обещаний, когда в глобальной среде есть обещания.

Можно добавить крошечный полифилл (проверьте мизинец-обещание ), но, на мой взгляд, нет смысла предоставлять полифилл. Лучше заставить пользователя обновить версию узла, чтобы использовать функции последнего узла. Действительно, проверьте (получил 6 PR) [https://github.com/sindresorhus/got/pull/140]. Зависимости не приветствуются в очень маленьких проектах и ​​используются везде.

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

Но, безусловно, согласовать асинхронность с обещаниями - это абсолютно _обязательно!

@Kikobeats : +1:

Обещания становятся первоклассными асинхронными функциями. Так что сложно представить необходимую библиотеку для асинхронности без их полной поддержки.

Я думаю, что это может быть реализовано без полифила, но с обнаружением функции: разрешить, если есть глобальный объект Promise с методом resolve .

@aearly bluebird добавляет совместимость с браузером в список полифиллинга. Думаю, было бы уместно его использовать.

@martinheidegger Bluebird слишком велик для этого. Он будет использовать 76 Кбайт (уменьшено) для простой поддержки методов обещания.

Опять же, использование интерфейса обратного вызова или обещаний в вашем внутреннем рабочем процессе - это естественный процесс, основанный на вашей версии узла.

  • Если у вас больше времени на бэкэнд (2 года или больше, возможно), вы используете версию 0.10 или 0.12 , поэтому ваш код написан в стиле обратного вызова.
  • Если у вас меньше 6 месяцев и вы используете версию >=4 node, вероятно, вы используете стиль Promise.

Но в любом случае у вас не смешанный стиль.

Поэтому нет необходимости добавлять зависимость для поддержки Promises; Если async когда-нибудь в будущем будет поддерживать обещания, вы можете использовать его, если ваша версия узла поддерживает обещания.

Крайний случай: _Я использую старую версию узла, но мой бэкэнд написан с использованием стиля обещаний_. Затем вы определили объект Promises как глобальный или определили его перед использованием async . Что вы хотите. Просто.

То же поведение и для внешнего интерфейса. Не нужна зависимость.

Хммм, похоже, все те же проблемы, которые были у Promises 4-5 лет назад. Если бы все использовали узел 4 или новее и современные браузеры с поддержкой ES6, мы могли бы легко использовать обещания внутри, где это применимо.

Проблема в том, что мы оставляем наших пользователей браузера node 0.12 и более ранних версий в пыли, требуя от них полифилла. Какой полифилл они используют? Мы не хотели бы объединять один, даже мизинец имеет вес. Кроме того, люди, которые используют обещания вне стандартного ES6 Promise, захотят использовать bluebird или q и т. Д., Что бы они ни использовали. Я не хочу требовать использования полифилла - npm i -S async должно быть всем, что нужно делать людям.

Async также был своего рода реакцией на Promises - альтернативный способ управления асинхронным кодом. Начать использовать Promises кажется шагом назад. Правильно управляемые обратные вызовы могут быть такими же мощными, как и обещания (и во многих случаях быстрее, поскольку в обещаниях есть встроенная отсрочка цикла событий).

Я полностью за взаимодействие с обещаниями, если функции передается Promise или другой «thennable», мы определенно должны этим воспользоваться. Но я думаю, что нам следует избегать создания и / или возврата обещаний внутри компании, просто потому, что поддержка ES6 на разных платформах еще предстоит.

Согласитесь, обещания не из дешевых в создании или исполнении. Я бы предпочел видеть что-то подобное в качестве расширения. Обещания прекрасны, но вы не всегда будете их хотеть

IMHO, после переноса большого количества кода узла на promises + co + yield, я не нашел прямой замены только для .eachLimit() . Наверное, список полезных кейсов намного меньше, чем кажется на первый взгляд, и с ним можно справиться отдельным пакетом.

Мне нравится небольшое расширение @Kikobeats , возможно, имеет смысл порекомендовать его в readme (/ cc @aearly).

Я был бы категорически против официальной поддержки обещаний в async по причинам, изложенным мной и другими пользователями.

@megawac А как насчет случая, когда функция возвращает обещание? например, пример @SEAPUNK .

@megawac Я Добавил поддержку стиля обратного вызова, тестов и сборки браузера в обещании-async . Тогда, если кто-то захочет использовать Promise, я думаю, что готово: +1:

@aearly , это было бы хорошо, я полагаю (так =), но я бы предпочел оставить это в плагине
приземлиться лично

Пт, 22 января 2016 г., в 14:17, Kiko Beats [email protected]
написал:

@megawac https://github.com/megawac Я Добавил поддержку стиля обратного вызова
и тесты для обещания-async
https://github.com/Kikobeats/promise-async#promise -async. Тогда если
кто-нибудь хочет использовать Promise, я думаю, он готов [image:: +1:]

-
Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/caolan/async/issues/956#issuecomment -174016628.

Вот еще один пакет, обещающий все доступные асинхронные методы:
https://github.com/eladnava/koa-async

Я думаю, что так же, как есть async.asyncify, может быть функция async.promisify.

Тогда я могу просто дождаться async.promisify (async.mapLimit (x, 10, mapper))

Я бы не стал возражать, если вы хотите создать запрос на перенос

В сб, 17 декабря 2016 г., в 16:57, Манодж Патель [email protected]
написал:

Я думаю, что так же, как async.asyncify, может быть async.promisify
функция.

Тогда я могу просто дождаться async.promisify (async.mapLimit (x, 10, mapper))

-
Вы получаете это, потому что вас упомянули.
Ответьте на это письмо напрямую, просмотрите его на GitHub
https://github.com/caolan/async/issues/956#issuecomment-267789633 или отключить звук
нить
https://github.com/notifications/unsubscribe-auth/ADUIEKJIDulPHAn_SeEZbiPb3t7ORGnpks5rJFqvgaJpZM4Gh1fr
.

Я использую метод promisifyAll модуля bluebird для преобразования обратных вызовов в обещания, чтобы методы async стали:

// adds '<original-method>Async' to class 
Promise.promisifyAll(async);

function somePromise() {
    return async.parallelAsync([
        function(cb) {
            setTimeout(function(){
                cb(new Error('err'), 'foo')
            }, 1000);
        },
        function(cb) {
            setTimeout(function(){
                cb(null, 'bar')
            }, 1000);
        }
    ]);
}

somePromise().then(function(result){
    console.log('result',result);
}).catch(function(err){
    console.log('err',err);
});

Пример JSFiddle

Была ли эта страница полезной?
0 / 5 - 0 рейтинги