<p>async.mapLimit 不返回 Promise</p>

创建于 2019-08-27  ·  14评论  ·  资料来源: caolan/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' 应该包含一个 Promise。 控制台应该记录 '2,4,6,8,10' 和 ' success:2 ,4,6,8,10'

实际结果如何?
它抛出一个错误:TypeError:无法读取未定义的属性“then”

注意:当我使用 'promise-async' 模块而不是 'async' 时,此代码运行良好。 文档说 async.mapLimit (和其他人)在没有提供回调时返回一个 Promise ,但我没有定义。 尚未找到任何工作样本(另请参阅我对“需要样本”问题的建议)。

最有用的评论

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)

Thx很多,合理的例子。 不幸的是,给了我“SyntaxError:await 仅在异步函数中有效”(对于 'await async.mapLimit')
还有什么我需要考虑的吗?

错误信息说明了一切,await 仅在异步函数中有效,直到实现顶级await 提议

叶,正在寻找一个完整的示例,因为这确实是我挣扎的部分。 不过没关系,终于启动并运行了:

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/await,当 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-async' 模块,它的工作方式与我预期的完全一样。

此外,我还没有理解为什么上面的 'Promise.all' 示例有效......这对我来说真的很困惑。

如果省略最终回调,则 iteratee 函数为async或使用回调不应影响返回承诺。 这是一个错误。

我敢打赌这与#1685有关

我敢打赌这与#1685有关

我绝对记得之前在我的代码示例的某些版本中也遇到过这个问题。 我认为显然这是由一些错误的编码引起的。 因此,有趣的是,它也以不同的口味出现。

我更多地研究了这个。

mapLimit正在按预期工作。 我敢打赌人们在这里看到的任何问题都是由于检测承诺返回函数的限制,或者编译器(例如 babel、typescript)没有保留async函数。

我更多地研究了这个。

mapLimit正在按预期工作。 我敢打赌人们在这里看到的任何问题都是由于检测承诺返回函数的限制,或者编译器(例如 babel、typescript)没有保留async函数。

处理async未在编译中保留的这种情况的最佳方法是什么?

此页面是否有帮助?
0 / 5 - 0 等级