js循环中的同步性仍在推动我前进。
我想做的很简单
async doAllTheThings(data, array) {
await array.forEach(entry => {
let val = //some algorithm using entry keys
let subVal = someFunc(/*more entry keys*/)
data[entry.Namekey] = `${val}/${subVal}`;
});
return data; //after data is modified
}
但是我不能确定那是否真正安全。我只是不喜欢简单的循环模式
for (i=0; i<arrayLength; i++) {
//do things
if (i === arrayLength-1) {
return
}
}
我想要一种更好的方法,但是我无法确定我正在尝试的内容是否安全运行,或者我只是没有找到会触发竞争条件的数据模式。
或者我想得太多了。数组中的算法仅由一些MATH和赋值语句组成...以及一个小的函数调用,其本身也仅由更多MATH和赋值语句组成。据说这些都是全面同步的。但是循环有时很奇怪。
问题
您可以在循环本身之外使用await来触发代码以等待循环完成吗?或者,这是唯一的安全方法,可以通过只检查循环中的位置,然后手动返回终点,直到返回终点,这才是老方法。
答案 0 :(得分:0)
处理异步和循环的最好方法之一是放一个诺言,然后等待Promise。所有人都记住await返回一个Promise,所以您可以这样做:
async function doAllTheThings(array) {
const promises = []
array.forEach((entry, index) => {
promises.push(new Promise((resolve) => {
setTimeout(() => resolve(entry + 1), 200 )
}))
});
return Promise.all(promises)
}
async function main () {
const arrayPlus1 = await doAllTheThings([1,2,3,4,5])
console.log(arrayPlus1.join(', '))
}
main().then(() => {
console.log('Done the async')
}).catch((err) => console.log(err))
另一种选择是使用generators,但它们要复杂一些,因此,如果您可以保存诺言并等待,那么这是一种更简单的方法。
最后的问题:
您可以在循环本身之外使用await来触发代码以等待循环完成吗?或者,这是唯一的安全方法,可以通过只检查循环中的位置,然后手动返回终点,直到返回终点,这才是老方法。
所有javascript循环都是同步的,因此下一行将等待循环执行。
如果您需要循环执行一些异步代码,则上述的promise方法是一种很好的方法。
异步循环的另一种方法是迭代器/生成器方法,特别是在必须“暂停”或从循环外部获取信息的情况下。
答案 1 :(得分:-1)
仅当您执行网络或I / O操作(发出网络请求,写入文件等)时,才需要进行异步等待(或承诺,在后台进行相同的操作)。
在循环中,您无需承诺,代码将同步执行。