如何解决如何在javascript中同步异步映射功能
我有一个异步映射函数,但希望它同步执行,因为我需要在同一循环中使用第一条语句的输出。但是,即使使用await语句,地图也可以异步运行,请您帮忙了解为什么会发生这种情况。
我的用例是,如果不存在,则将记录插入mongodb;如果存在循环,则对其进行更新。 数据存在于db中,但在循环中查找失败,但在外部可用。
我的代码:
@IBAction func keypressed(_ sender: UIButton) {
if sender.isSelected {
sender.backgroundColor = .clear
} else {
sender.backgroundColor = .green
}
sender.isSelected.toggle()
}
我得到的日志:
const doSomethingAsync = () => {
return new Promise(resolve => {
setTimeout(() => {
resolve(Date.Now());
},1000);
});
};
await Promise.all(
modelVarients.map(async varient => {
console.log(`varient: ${varient._id}`);
console.log('1');
const onlineDevice = await Device.findOne({
model: varient._id,});
console.log('2');
await doSomethingAsync();
console.log('3');
await doSomethingAsync();
console.log(JSON.stringify(onlineDevice));
await doSomethingAsync();
console.log('4');
return varient;
})
);
但是我希望得到什么:
varient: 8 pro
1
varient: note
1
varient: iphone x
1
2
2
2
3
3
3
null
null
null
4
4
4
解决方法
modelVarients.map(async () => >...)
将所有元素转换为Promises,这意味着它们都开始执行。然后Promise.all()
收集它们并等待所有它们,这就是为什么您可以使用此结构来等待map
完成的原因。这是并行处理。
您需要的是顺序处理,您可以使用reduce
进行处理,如下所示:
await modelVarients.reduce(async (memo,varient) => {
await memo;
// all the other things
},Promise.resolve())
reduce
在某种意义上类似于map
,它为数组中的所有元素创建了一个Promise,但是有一个当前值从一个元素到另一个。在这种情况下,第一个是Promise.resolve()
,第二个是第一个的结果,依此类推。使用await memo
,您可以等待上一个结果。
使用reduce
,最后一个元素将等待上一个元素,然后等待上一个元素,依此类推,因此不需要Promise.all。
我已经撰写了有关map和reduce如何与异步功能一起使用的文章,它们将帮助您了解大局。
,看来您应该 chain 您的诺言,而不是与Promise.all
并行运行
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。