<p>async.mapLimit не возвращает обещание</p>

Созданный на 27 авг. 2019  ·  14Комментарии  ·  Источник: caolan/async

Какую версию async вы используете?
3.1.0

В какой среде возникла проблема (версия узла / версия браузера)
узел 12.9.1, npm 6.10.2, браузер Н / Д

Что ты сделал?
Проблема имеет поток в stackoverflow
https://stackoverflow.com/questions/57622495/async-maplimit-with-promise/57659221#57659221

В принципе, у меня есть такой код:

async = require('async');
let numPromise = async.mapLimit(['1','2','3','4','5'], 3, function(num, callback){
    setTimeout(function(){
        num = num * 2,
        console.log(num);
        callback(null, num);
    }, 
    2000);
})
numPromise
.then((result) => console.log("success:" + result))
.catch(() => console.log("no success"));

Чего вы ожидали?
Выполнить без ошибок, numPromise должен содержать обещание. консоль должна регистрировать «2,4,6,8,10» и « успех: 2 , 4,6,8,10»

Каков был реальный результат?
Выдает ошибку: TypeError: невозможно прочитать свойство then of undefined

Примечание. Когда я использую модуль «обещание-асинхронный» вместо «асинхронный», этот код работает хорошо. В документации говорится, что async.mapLimit (и другие) возвращают обещание, когда обратный вызов не предоставляется, но я получаю значение undefined. Не удалось найти ни одного рабочего образца (см. Также мое предложение по проблеме «нужны образцы»).

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

const async = require('async');
const delay = require('util').promisify(setTimeout);
const numPromise = async.mapLimit(['1','2','3','4','5'], 3, async num => delay(200).then(() => num*2))
// or const numPromise = async.mapLimit(['1','2','3','4','5'], 3, async num => {
//    await delay(200);
//    return num*2;
// })
numPromise.then(console.log)

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

const async = require('async');
const delay = require('util').promisify(setTimeout);
const numPromise = async.mapLimit(['1','2','3','4','5'], 3, async num => delay(200).then(() => num*2))
// or const numPromise = async.mapLimit(['1','2','3','4','5'], 3, async num => {
//    await delay(200);
//    return num*2;
// })
numPromise.then(console.log)

Спасибо большое, разумный пример. К сожалению, выдает мне «SyntaxError: await действительно только в асинхронной функции» (для 'await async.mapLimit')
Что еще я должен учесть?

Сообщение об ошибке говорит само за себя, ожидание действует только в асинхронной функции, пока не будет реализовано предложение верхнего уровня ожидания.

Ип, искал полностью рабочий пример, так как это действительно та часть, с которой я боролся. Неважно, наконец-то запустил:

const myAsyncFunction = async function(){
    //const numPromise = await async.mapLimit(['1','2','3','4','5'], 3, async num => delay(200).then(() => num*2))
    const numPromise = await async.mapLimit(['1','2','3','4','5'], 3, async num => {
        await delay(2000);
        console.log(num*2);
        return num*2;
     })
    //numPromise.then(console.log)
    return numPromise;
}
myAsyncFunction()
.then((result) => console.log(result));

Я еще не совсем уверен, чем отличается от предыдущих попыток, но проверю и добавлю еще несколько выводов по этому поводу.
В любом случае, я считаю, что все это не совсем интуитивно понятно, поэтому подобные примеры могут помочь!
И ... я до сих пор не совсем понимаю, почему нам нужно обернуть вокруг него все async / awaits, когда async.mapLimit должен просто возвращать простой Promise сам по себе ...

упс, я забыл ожидание в моем предыдущем коде, отредактировал

Хорошо, теперь я полностью подтверждаю :-) Так что, вероятно, главная проблема заключалась в том, что функция iteratee не была полностью асинхронной?
В любом случае, кажется, это работает как шарм и, вероятно, также является отличным примером! Спасибо, что остались со мной !!

См. Https://github.com/caolan/async/issues/1673, чтобы узнать, почему

async.mapLimit(['1','2','3','4','5'], 3, async num => delay(200).then(() => num*2)) // works

async.mapLimit(['1','2','3','4','5'], 3, num => delay(200).then(() => num*2)) // doesn't work

Promise.all(['1','2','3','4','5'].map(num => delay(200).then(() => num*2))) // works (plain promises)

Вижу, ты полностью со мной, т.е. были такие же проблемы.
Я предполагаю, что моя основная мысль на самом деле заключается в следующем - в документации просто указано «Возврат: обещание, если обратный вызов не передан» - поэтому, когда у меня есть вариант обратного вызова, а затем просто не учитывается, как я могу прийти к выводу, что мне нужно чтобы добавить ключевое слово async, когда оно работало без этого в версии обратного вызова. Кроме того, при использовании модуля «обещание-асинхронизация» он работает именно так, как я ожидал.

Кроме того, я еще не понял, почему работает приведенный выше пример «Promise.all» ... это меня действительно сбивает с толку.

Функция iteratee, являющаяся async или использующая обратный вызов, не должна влиять на возврат обещания, если последний обратный вызов опущен. Это ошибка.

Готов поспорить, это связано с # 1685

Готов поспорить, это связано с # 1685

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

Я изучил это подробнее.

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

Я изучил это подробнее.

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

Как лучше всего справиться с такими сценариями, когда async не сохраняется при компиляции?

Оберните функцию async в asyncify . http://caolan.github.io/async/v3/global.html#AsyncFunction

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