最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Why does async array map return promises, instead of values - Stack Overflow

programmeradmin2浏览0评论

See the code below

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]

Quick edit: The accepted answer is correct, by saying that map doesnt do anything special to async functions. I dont know why i assumed it recognizes async fn and knows to await the response.

I was expecting something like this, perhaps.

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.

See the code below

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]

Quick edit: The accepted answer is correct, by saying that map doesnt do anything special to async functions. I dont know why i assumed it recognizes async fn and knows to await the response.

I was expecting something like this, perhaps.

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.
Share Improve this question edited Nov 29, 2017 at 17:14 Rainer Plumer asked Nov 29, 2017 at 16:10 Rainer PlumerRainer Plumer 3,7533 gold badges28 silver badges42 bronze badges 1
  • Why would you expect any different when you are clearly returning new Promise for each value – musefan Commented Nov 29, 2017 at 16:13
Add a ment  | 

2 Answers 2

Reset to default 16

Because an async function always returns a promise; and map has no concept of asynchronicity, and no special handling for promises.

But you can readily wait for the result with Promise.all:

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

Live Example:

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
    }
})();
.as-console-wrapper {
  max-height: 100% !important;
}

or using Promise callbacks:

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

Live Example:

var arr = [1,2,3,4,5].map(async (index) => { 
    return await new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(index);
            console.log(index);
        }, 1000);
    });
});
Promise.all(arr)
    .then(results => {
        console.log(results);
    })
    .catch(err => {
        // Handle error
    });
.as-console-wrapper {
  max-height: 100% !important;
}


Side note: Since async functions always return promises, and the only thing you're awaiting in your function is a promise you create, it doesn't make sense to use an async function here anyway. Just return the promise you're creating:

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

Of course, if you're really doing something more interesting in there, with awaits on various things (rather than just on new Promise(...)), that's different. :-)

Since it is async, the values have not been determined at the time map returns. They won't exist until the arrow function has been run.

This is why Promises exist. They are a promise of a value being available in the future.

发布评论

评论列表(0)

  1. 暂无评论