javascript - 如何在 .map 中使用多个等待?
问题描述
我知道我们不能简单地做这样的事情:
myArray.forEach(async x => await asyncOperation())
编辑:我知道这是有效的,但我需要按正确的顺序排列
如果我们必须使用异步操作遍历数组,我必须改为:
await Promise.all(myArray.map(x => asyncOperation()))
但是,我需要在同一迭代中执行两个异步操作。我知道另一种选择是只使用.reduce
它看起来像这样:
await myArray.reduce((p, el) => {
return p.then(() => {
return somePromise(el)
.then(res => {
return anotherPromise(res)
})
})
}, Promise.resolve())
但我正在避免嵌套承诺,并希望仅使用async/await
. 所以无论如何,我的问题是,迭代需要通过两个承诺的数组的最佳等待时间是什么?
解决方案
async
/await
很棒,但它们并不是所有使用承诺的代码的 100% 替代品。有时(例如,当您需要使用时Promise.all
)您确实需要将承诺用作值本身,而不是在async
/内部秘密使用await
。
有一些方法可以避免这样做,比如避免使用 ES6map
和其他数组迭代方法,而是使用for
循环......但通常这样做是......好吧,治愈比疾病更糟糕。只需使用承诺。
编辑:
这是一个基于评论反馈的基本示例。假设您有两个(或更多)URL,并且想要获取第一个然后(在它返回之后),获取下一个,一旦它们全部被获取,就做其他事情。如果您尝试使用 ES6 数组方法同步执行此操作,即使您使用async
/ await
,它也不起作用:
const urls = ['www.example.com/1', 'www.example.com/2'].
var promises = urls.map(async url => await fetch(url));
Promise.all(promises).then(doSomethingElse);
该代码实际上会立即获取所有 URL;它不会等到第一个完成后才获取第二个。
为此,您可以将async
/await
与for
循环一起使用并避免 ES6 的东西(大概以下内容在async
函数内部):
const urls = ['www.example.com/1', 'www.example.com/2'].
const pageHtml = [];
for (var i = 0; i < promises.length; i++) {
const url = urls[i];
const html = await fetch(url));
pageHtml.push(html);
}
doSomethingElse(); // no need for Promise.all!
...但是您使用for
的是 1999 年的循环;哎呀!我认为更好的解决方案是使用现代 Javascript,但不要将async
/await
用于所有内容。
大多数时候使用这些关键字,但是当您需要使用Promise.all
递归函数时(如果您需要“在 #2 之后获取 #1”部分;请参阅@jcubic 的答案以了解可能的实现),或者如果您不使用只是这样做:
const urls = ['www.example.com/1', 'www.example.com/2'].
var promises = urls.map(fetch);
Promise.all(promises).then(doSomethingElse);
是的,您正在避免async
/await
并直接使用数组或 Promise 对象Promise.all
... 但是代码简短明了,可以满足您的需求。您不必总是使用这些关键字。
推荐阅读
- python-3.x - python中的类[_]等价物
- javascript - 获取警报并在底部获取文本
- database - 有没有人有管理 Cassandra 部署的好方法
- azure - 无法认证,需要:mac的承载授权
- angular - 使用 .find 方法在角度中使用 jest 对数组进行单元测试
- flutter - Flutter 自动打印任何 http 请求 - 抽象 HTTP 类
- python - 在 scipy 的牛顿函数中输入一个数组作为初始猜测
- arrays - Vue v-for:使用事件处理程序(@change)从数组动态填充 HTML 到组件模板中
- django - 为什么我的 ViewSet 在使用 get_object_or_404 使用 for loop ang 后继续循环?
- python - 将类或函数导入“unittest”测试模块的最佳实践是什么