JavaScript中的循环是同步还是异步?(for,while等)
假设我有:
for(let i=0; i<10; i++){
// A (nested stuff...)
}
// B ...
Run Code Online (Sandbox Code Playgroud)
使用for执行B会在A有时开始...(所以异步)
有没有办法以同步方式使用语句?
jam*_*non 18
当所有异步操作都启动时,for循环立即运行完成.
好吧,这里有一些嵌套循环.请注意,"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')
Run Code Online (Sandbox Code Playgroud)
现在,看看这个
for(let i=0; i<10; i++){
setTimeout(function() {console.log("AA")}, 2000)
}
console.log('BBB')
Run Code Online (Sandbox Code Playgroud)
这是因为所谓的"事件循环".事实上,使用setTimeout我们正在模拟异步操作.它可能是ajax调用或其他异步进程.
看看这个:http://latentflip.com/loupe
这将真正帮助您了解这些异步/同步循环主题.
更新以显示承诺如何在这里工作(给出以下评论):
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"]
);
Run Code Online (Sandbox Code Playgroud)
如果我不够清楚,请告诉我.
如果您将异步循环放在a内,for...loop并希望停止循环直到每个操作结束,则必须使用如下async/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*/ })
Run Code Online (Sandbox Code Playgroud)
首先,你关于“用于 B 的执行有时会在 A 之前开始......(所以异步) ”的说法是错误的。
Javascript中的循环函数(如while、for或)将同步运行(阻塞.forEach) ,无论您是在浏览器中运行还是在NodeJS等运行时环境中运行。我们可以通过运行下面的代码来证明这一点(也许这个过程需要几秒钟):.map
let counter1 = 0
let counter2 = 0
let counter3 = 0
console.log("Start iteration")
console.time("Time required")
// First heavy iteration
for (let i = 0; i < 1000; i++) {
counter1 += 1
// Second heavy iteration
for (let i2 = 0; i2 < 1000; i2++) {
counter2 += 1
// Third heavy iteration
for (let i3 = 0; i3 < 1000; i3++) {
counter3 += 1
}
}
}
console.log("Iteration was successful")
console.timeEnd("Time required")
console.log('The value of `counter1` is: ' + counter1)
console.log('The value of `counter2` is: ' + counter2)
console.log('The value of `counter3` is: ' + counter3)Run Code Online (Sandbox Code Playgroud)
那么什么样的循环会导致您的代码异步运行(非阻塞)?
答案是:
放置在
Promise回调或functionwith关键字或一些带有回调(并非全部)async的本机函数(如、等)内的代码将异步运行。setTimeoutsetInterval
例子:
setTimeout(() => {
console.log('A')
})
console.log('B')Run Code Online (Sandbox Code Playgroud)
在代码中,
setTimeout首先声明函数。但是,代码的输出显示该console.log('B')函数的运行时间早于该setTimeout函数。
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);
}
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
28936 次 |
| 最近记录: |