javascript中的同步和异步循环
JavaScript中的循环是同步的还是异步的?(暂时等) 假设我有:javascript中的同步和异步循环,javascript,Javascript,JavaScript中的循环是同步的还是异步的?(暂时等) 假设我有: for(let i=0; i<10; i++){ // A (nested stuff...) } // B ... for(让i=0;ifor循环在所有异步操作启动时立即运行到完成 这里我们有一些嵌套循环。注意,“BBB”总是在后面触发 for(let i=0; i<10; i++){ for(let i=0; i<10; i++){ for(let i=0; i<10;
for(let i=0; i<10; i++){
// A (nested stuff...)
}
// B ...
for(让i=0;ifor循环在所有异步操作启动时立即运行到完成
这里我们有一些嵌套循环。注意,“BBB”总是在后面触发
for(let i=0; i<10; i++){
for(let i=0; i<10; i++){
for(let i=0; i<10; i++){
console.log("AA")
}
}
}
console.log('BBB')
如果我不够清楚,请告诉我。如果您将异步循环放置在for…循环中,并希望在每次操作结束前停止循环,则必须使用以下异步/await
语法
async function foo() {
var array = [/* some data that will be used async*/]
//This loop will wait for each next() to pass the next iteration
for (var i = 0; i < array.length; i++) {
await new Promise(next=> {
someAsyncTask(array[i], function(err, data){
/*.... code here and when you finish...*/
next()
})
})
}
}
foo().then(() => { /*After foo execution*/ })
异步函数foo(){
var数组=[/*将异步使用的某些数据*/]
//此循环将等待每个next()通过下一次迭代
对于(var i=0;i{
someAsyncTask(数组[i],函数(错误,数据){
/*..在这里编码,完成后*/
下一个()
})
})
}
}
foo()。然后(()=>{/*在foo执行之后*/})
首先,您关于“用于执行B的语句有时会在A之前开始…(如此异步)”是错误的
Javascript中的循环函数(如while
,for
,.forEach
或.map
)将同步运行(阻塞),无论您是在浏览器中还是在NodeJS等运行时环境中运行它。我们可以通过运行下面的代码来证明这一点(过程可能需要几秒钟):
让计数器1=0
设计数器2=0
设计数器3=0
log(“开始迭代”)
控制台时间(“所需时间”)
//第一次重迭代
for(设i=0;i<1000;i++){
计数器1+=1
//第二重迭代
for(设i2=0;i2<1000;i2++){
计数器2+=1
//第三重迭代
for(设i3=0;i3<1000;i3++){
计数器3+=1
}
}
}
log(“迭代成功”)
控制台。时间结束(“所需时间”)
log('counter1'的值为:'+counter1)
console.log('counter2'的值为:'+counter2)
console.log('counter3'的值为:'+counter3)
“使用for
执行B
有时会在A
之前开始”你能创建一个stacksnippets来演示吗?@guest271314它可以是任何东西,更多的嵌套语句、ajax、逻辑等等for
循环是同步的。B
不应该在for
循环完成之前执行。你能演示B
的情况吗在for
循环完成之前开始执行?在for
循环中是否有异步操作,在B
开始执行之后,这些异步操作可能在将来某个时候才会被调用?请参阅。将出现的情况是,为执行异步I/O的函数注册的回调(例如)在之后被调用RB已执行。但是,上面的代码按顺序运行,稍后会调用您的回调。我是否应该创建一个类似于承诺在间隔后解决的问题?好吧,不是在您最初的问题中,因为给定一个标准循环-它将始终在“BBB”之前运行到完成发生了。但是,我猜你有一些排序异步操作,“可能需要一些时间”,然后“BBB”出现在前面,对吗?这很好。但是如果我想打破循环,该怎么办?达尼,这不是“同步的”类型loop-所有超时同时触发;只是等待被1000*idx
交错,您可以添加一个break;语句。代替使用let i,使用let a、b、c、a作为第一个循环,b作为第二个循环等等。然后,例如,在内部循环中,类型:if(a>=1)break;,您将看到循环的其他部分没有运行。这就是您的意思吗?foo()之后的任何代码都将在循环中someAsyncTask
之前运行。@tiomno是的,这是因为foo是一个承诺,只需将该代码放入foo()。然后(()=>{/*您的代码在这里*/})
谢谢!这是一个真正的异步循环,因为每次运行都在触发前等待上一次。只要跳过someAsyncTask()
函数调用,但仍在执行next(),就可以在满足条件时“跳过”掉
这样无论怎样,然后..
部分都会完成。这应该是选择的答案。在这种方法中,如果我想在我的someAsyncTask
中增加一些延迟,那么最好的方法是什么?@GauravAgrawal等待新的承诺(res=>setTimeout(=>res(),3000))虽然此代码片段可能是解决方案,但包含解释确实有助于提高您的文章质量。请记住,您将在将来为读者回答这个问题,而这些人可能不知道您的代码建议的原因。
var stringValues = ['yeah', 'noooo', 'rush', 'RP'];
var P = function(val, idx){
return new Promise(resolve => setTimeout(() => resolve(val), 1000 * idx));
};
// We now have an array of promises waiting to be resolved.
// The Promise.all basically will resolve once ALL promises are
// resolved. Keep in mind, that if at any time something rejects
// it stops
// we iterator over our stringValues array mapping over the P function,
// passing in the value of our array.
var results = Promise.all(stringValues.map(P));
// once all are resolved, the ".then" now fires. It is here we would do
results.then(data =>
console.log(data) //["yeah", "noooo", "rush", "RP"]
);
async function foo() {
var array = [/* some data that will be used async*/]
//This loop will wait for each next() to pass the next iteration
for (var i = 0; i < array.length; i++) {
await new Promise(next=> {
someAsyncTask(array[i], function(err, data){
/*.... code here and when you finish...*/
next()
})
})
}
}
foo().then(() => { /*After foo execution*/ })
let items = YourArray;
let i = 0;
await new Promise(async (resolve, reject) => {
try {
if (items.length == 0) return resolve();
let funSync = async () => {
await yourASyncFunctions(items[i].doAnything);
i++;
if (i == items.length) resolve();
else funSync();
}
funSync();
} catch (e) {
reject(e);
}
});
for(const elment of arrayElements) {
await yourFunc(elment)
await yourOtherFunc('somePatameter')
}