Javascript,Promises和setTimeout [英] Javascript, Promises and setTimeout
问题描述
我一直在玩Promises,但是我在理解以下代码发生了什么时遇到了麻烦:
const promise =新的Promise((解决,拒绝)=> {
console.log('承诺开始-异步代码已开始')
setTimeout(()=> {
resolve('Success ')
},10)
})
setTimeout(()=> {
console.log('第一个setTimeout中的承诺日志')
},0)
promise.then(res => {
console.log('完成后的承诺日志')
})
console.log('承诺已完成-同步代码已终止')
setTimeout(()=> {
console.log('在第二setTimeout中的承诺日志')
},0)
输出为:
$后的承诺日志p $ p>
承诺已开始-异步代码已开始
承诺已完成-同步代码已终止
承诺日志在第一个setTimeout内
承诺日志在第二个setTimeout内
完成
符合预期。
但是让我们检查以下代码的输出:
const promise = new Promise((resolve,reject)=> {
console.log('承诺开始-异步代码开始')
setTimeout(()=> {
resolve('Success')
},1)
})
setTimeout(()=> {
console.log('第一个setTimeout内的承诺日志')
},0)
promise.then(res => {
console.log('完成后的承诺日志')
})
console.log('承诺已完成-同步代码已终止')
setTimeout(()=> {
console.log('第二个setTimeout中的承诺日志')
},0)
将要解决的承诺setTimeout计时器值从10ms更改为1ms
输出为:
承诺已开始-异步代码已开始
承诺取得-同步代码在完成
后的终止日志
在第一个setTimeout内的承诺日志
在第二个setTimeout内的承诺日志
对此有任何解释吗?
解决方案我将使用以下示例进行解释:
setTimeout(()=> {
console.log('1 ms timeout');
},1); //时间移至T0
setTimeout(()=> {
console.log('0 ms timeout')
},0);移至异步队列//在setTimeout的同步调用花费1 ms后移到异步队列,即在T1
// //在T1处,队列将是[( 1ms timeout,0),( 0ms timeout,0)]
因此,这将打印
1毫秒超时
0毫秒超时
以上理解:
调用setTimeouts是同步的(即使其回调已放入异步队列中),即我们调用setTimeout()并移至下一条语句-此同步操作本身可能需要1毫秒。
换句话说,1ms的时间太短了,所以当JS引擎看到第二个异步语句时,第一个已经在队列中花费了1ms。 p>
我还建议您尝试以下方法
setTimeout(()= > {
console.log( First);
},2); //在T0处排队= [( First,2)]
const forLoopLimit = 100;
for(var i = 0; i< forLoopLimit; i ++){
console.log(i * 10000);
} //假设大约需要3毫秒
//在T3排队= [( First,0)]
setTimeout(()=> {
控制台.log( Second);
},0); //假设需要0毫秒。
//在T4排队= [( First,0),( Second,0)]
这将在
之前打印第二
之前打印First
,即使前者的超时时间为2ms,后者0毫秒
现在将forLoopLimit
更改为1甚至10,您将看到同步任务现在不需要3毫秒,并且Second
在First
另外值得尝试的是:
console.log(Date.now());
console.log(Date.now());
多次尝试以上操作,您会发现有时控制台日志会有不同的时间戳。大致来说,您可以说
console.log()
和Date.now()
花费0.5毫秒。只是时间来调用/执行同步的东西。I have been playing with Promises, but I am having trouble understanding what is happening with the following code:
const promise = new Promise((resolve, reject) => { console.log('Promise started - Async code started') setTimeout(() => { resolve('Success') }, 10) }) setTimeout(() => { console.log('Promise log inside first setTimeout') }, 0) promise.then(res => { console.log('Promise log after fulfilled') }) console.log('Promise made - Sync code terminated') setTimeout(() => { console.log('Promise log inside second setTimeout') }, 0)
The output is:
Promise started - Async code started Promise made - Sync code terminated Promise log inside first setTimeout Promise log inside second setTimeout Promise log after fulfilled
It is as expected.
But let check the output of the below code:
const promise = new Promise((resolve, reject) => { console.log('Promise started - Async code started') setTimeout(() => { resolve('Success') }, 1) }) setTimeout(() => { console.log('Promise log inside first setTimeout') }, 0) promise.then(res => { console.log('Promise log after fulfilled') }) console.log('Promise made - Sync code terminated') setTimeout(() => { console.log('Promise log inside second setTimeout') }, 0)
Changed the to be resolved promise setTimeout timer value from 10ms to 1ms
The output is:
Promise started - Async code started Promise made - Sync code terminated Promise log after fulfilled Promise log inside first setTimeout Promise log inside second setTimeout
Any explanation for this?
解决方案I will use the following example to explain:
setTimeout(() => { console.log('1 ms timeout'); }, 1); // Moved to async queue at time = T0 setTimeout(() => { console.log('0 ms timeout') }, 0); // Moved to async queue after 1 ms that synchronous call to setTimeout takes i.e. at T1 // So at T1, queue will be [("1ms timeout", 0), ("0ms timeout", 0)]
Hence this will print
1 ms timeout 0 ms timeout
Understanding of above: Calling setTimeouts is synchronous (even though its callback is put in async queue), i.e. we call setTimeout() and move to next statement - this synchronous action itself may take 1ms.
In other words, 1ms is too low a time so by the time JS engine sees the 2nd async statement, the first one has already spent 1ms in the queue.
I also suggest you try out the following
setTimeout(() => { console.log("First"); }, 2); // queue at T0 = [("First", 2)] const forLoopLimit = 100; for (var i = 0; i < forLoopLimit; i++){ console.log(i * 10000); } // Assume that it takes about 3 milliseconds // queue at T3 = [("First", 0)] setTimeout(() => { console.log("Second"); }, 0); // Assume it takes 0 milliseconds. // queue at T4 = [("First", 0), ("Second", 0)]
This will print
First
beforeSecond
even though the former had 2ms timeout compared to the latter having 0ms. Now changeforLoopLimit
to 1 or even 10, you'll see that the synchronous task doesn't take 3 milliseconds now, andSecond
is printed beforeFirst
Also worth trying is:
console.log(Date.now()); console.log(Date.now());
Try above multiple times and you'll see that sometimes console logs will have different timestamps. Roughly, you can say
console.log()
andDate.now()
take 0.5ms. It's nothing but the time to call / execute synchronous stuff.这篇关于Javascript,Promises和setTimeout的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文