为什么JS中map函数返回promise数组而非直接返回img对象?
原理说明
核心差异是await生效的作用域不同:
- 在
loadNPause函数中,await直接写在当前async函数的顶层逻辑中,作用就是等待createImage返回的Promise执行完成,直接返回Promise resolve的结果(也就是img DOM对象),所以你打印出来的是img对象而非Promise。 - 在
loadAll的map遍历逻辑中,await写在map的独立async回调函数内部:map方法是同步执行的,不会等待任何回调内部的异步逻辑完成,只会同步收集每个回调的返回值。而async函数的返回值永远会被包裹为Promise,所以不管你是写async img => await createImage(img)还是img => createImage(img),map最终返回的都是Promise数组:- 前者是async回调把返回的img对象包装成了Promise
- 后者是直接收集
createImage本身返回的Promise
如果你想要在遍历的时候直接拿到每个img对象,必须用Promise.all包裹整个Promise数组后再await,也就是你代码中imgsEl = await Promise.all(imgs)这一步,拿到的imgsEl才是实际的img对象数组。
简化示例辅助理解
// 模拟返回Promise的方法 const getValue = (val) => Promise.resolve(val); // 场景1:await直接在当前async函数内 const testDirectAwait = async () => { const res = await getValue(1); console.log(res); // 输出 1,是实际值不是Promise }; // 场景2:await在map的async回调内 const testMapAwait = async () => { const promiseArr = [1,2,3].map(async (num) => { return await getValue(num); }); console.log(promiseArr); // 输出 [Promise, Promise, Promise] const realRes = await Promise.all(promiseArr); console.log(realRes); // 输出 [1,2,3],是实际值数组 };
内容的提问来源于stack exchange,提问作者venndi
相关产品推荐
相关产品推荐

