为什么异步数组映射返回承诺而不是值

Rai*_*mer 1 javascript promise async-await

见下面的代码

var arr = await [1,2,3,4,5].map(async (index) => { 
    return await new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(index);
            console.log(index);
        }, 1000);
    });
});
console.log(arr); // <-- [Promise, Promise, Promise ....]
// i would expect it to return [1,2,3,4,5]
Run Code Online (Sandbox Code Playgroud)

快速编辑:通过说map对异步功能没有做任何特殊的事情,可接受的答案是正确的。我不知道为什么我认为它可以识别异步fn并知道等待响应。

也许我期待这样的事情。

Array.prototype.mapAsync = async function(callback) {
    arr = [];
    for (var i = 0; i < this.length; i++)
        arr.push(await callback(this[i], i, this));
    return arr;
};

var arr = await [1,2,3,4,5].mapAsync(async (index) => { 
    return await new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(index);
            console.log(index);
        }, 1000);
    });
});
// outputs 1, 2 ,3 ... with 1 second intervals, 
// arr is [1,2,3,4,5] after 5 seconds.
Run Code Online (Sandbox Code Playgroud)

T.J*_*der 5

因为一个async函数总是返回一个promise;并且map没有异步性的概念,也没有对诺言的特殊处理。

但是您可以使用以下命令随时等待结果Promise.all:

try {
    const results = await Promise.all(arr);
    // Use `results`, which will be an array
} catch (e) {
    // Handle error
}
Run Code Online (Sandbox Code Playgroud)

现场示例:

try {
    const results = await Promise.all(arr);
    // Use `results`, which will be an array
} catch (e) {
    // Handle error
}
Run Code Online (Sandbox Code Playgroud)
var arr = [1,2,3,4,5].map(async (index) => { 
    return await new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(index);
            console.log(index);
        }, 1000);
    });
});
(async() => {
    try {
        console.log(await Promise.all(arr));
        // Use `results`, which will be an array
    } catch (e) {
        // Handle error
    }
})();
Run Code Online (Sandbox Code Playgroud)

或使用Promise语法

Promise.all(arr)
    .then(results => {
        // Use `results`, which will be an array
    })
    .catch(err => {
        // Handle error
    });
Run Code Online (Sandbox Code Playgroud)

现场示例:

.as-console-wrapper {
  max-height: 100% !important;
}
Run Code Online (Sandbox Code Playgroud)
Promise.all(arr)
    .then(results => {
        // Use `results`, which will be an array
    })
    .catch(err => {
        // Handle error
    });
Run Code Online (Sandbox Code Playgroud)


旁注:由于async函数总是返回promise,而函数中唯一要显示的是await您创建的promise,因此async无论如何在这里使用函数都没有意义。只需返回您正在创建的承诺即可:

var arr = [1,2,3,4,5].map((index) => { 
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(index);
            console.log(index);
        }, 1000);
    });
});
Run Code Online (Sandbox Code Playgroud)

当然,如果您确实在其中做一些更有趣的事情,并且await在各种事物上使用s(而不是仅仅在上new Promise(...)),那就不一样了。:-)