进程与线程 我们经常说 JavaScript 是一门单线程语言,指的是一个进程里只有一个主线程,那到底什么是线程?什么是进程? 首先需要把这个问题搞明白。...('setTimeout'); }, 0); Promise.resolve().then(function() { console.log('promise1'); }).then(function...') },0) }) setTimeout(()=>{ console.log('setTimeout1') Promise.resolve().then(()=>{ console.log...() { console.log('promise1') }) }, 0) setTimeout(() => { console.log('timer2') Promise.resolve...首先 setTimeout(fn, 0) === setTimeout(fn, 1) ,这是由源码决定的,进入事件循环也是需要成本的,如果在准备时候花费了大于 1ms 的时间,那么在 timer 阶段就会直接执行
这就是为什么当浏览器解析 JavaScript 代码时为什么会阻塞页面渲染,因为这两个事务在同一个线程里。...setTimeout(() => { console.log(1); Promise.resolve(2).then(n => console.log(n)); },0); setTimeout...此时微任务队列中有什么?...{ console.log('promise1'); }); }, 0); setTimeout(() => { console.log('timer2') Promise.resolve...') Promise.resolve().then(function() { console.log('promise2'); }); }, 0); Promise.resolve().
,但其状态还是为pending,这里理解为先不执行 执行同步代码4 一轮循环过后,进入第二次宏任务,发现延迟队列中有setTimeout定时器,执行它 首先执行timerStart,然后遇到了resolve...0) }, 0) setTimeout(() => { console.log('timer2') }, 0) console.log('start') 复制代码 (2) setTimeout((...) => { console.log('timer1'); Promise.resolve().then(() => { console.log('promise') }) }, 0...console.log('timer2') }, 0) }); const timer1 = setTimeout(() => { console.log('timer1') Promise.resolve...1 遇到定时器timer1,将它加入下一次宏任务的延迟列表,标记为宏2,等待执行(先不管里面是什么内容) 执行宏1中的同步代码start 第一次宏任务(宏1)执行完毕,检查第一次的微任务队列(微1),发现有一个
new Promise出来的实例,成功或者失败,取决于executor函数执行的时候,执行的是resolve还是reject决定的,或executor函数执行发生异常错误,这两种情况都会把实例状态改为失败的...接下来,我们一步一步分析: 首先执行同步代码,输出 1,遇见第一个setTimeout,将其回调放入任务队列(宏任务)当中,继续往下执行 运行run(),打印出 5,并往下执行,遇见 await fn(...),将其放入任务队列(微任务) await fn() 当前这一行代码执行时,fn函数会立即执行的,打印出3,遇见第二个setTimeout,将其回调放入任务队列(宏任务),await fn() 下面的代码需要等待返回...值得注意的是,这个定时器 推迟时间0毫秒实际上达不到的。根据HTML5标准,setTimeOut推迟执行的时间,最少是4毫秒。...executor函数执行,打印出8,然后在执行resolve时,触发微任务,于是打印出9 最后执行第一个setTimeout的宏任务,打印出2 常用的方法 1、Promise.resolve() Promise.resolve
让我们为脚本添加一些更多的代码并且再次运行它: 等下,发生了什么?! 首先,Start! 被输出。 好的,我们已经看到了那一个即将到来的消息:console.log('Start!')...尽管我们为计时器提供的值是 0,在它被添加到宏任务队列 (setTimeout 是一个宏任务) 之后回调还是会被首先推入 Web API。...到了去检查宏任务队列的时候了:setTimeout 回调仍然在那里等待!setTimeout 被弹入调用栈。回调函数返回 console.log 方法,输出了字符串 In timeout!。...很好,但这到底是什么意思? 当我们运行下面的代码块时让我们看下发生了什么: 额,这里发生了什么呢? 首先,JavaScript 引擎遇到了 console.log。...最先发生的事是被等待的值执行:在这个例子中是函数one。它被弹入调用栈,并且最终返回一个解决状态的promise。
还是输出: time is up ⏰ 是后者,因为当一个Promise resolved 后,它就不能再被rejected。...它包含两个参数,一个用于成功执行,另一个则在发生错误时使用。...我们可以使用Promise.all,它通常在启动多个异步任务并发运行并为其结果创建承诺之后使用,以便人们可以等待所有任务完成。...还是2秒? 这个留给你们自己验证咯。...达到限制后,我们使用Promise.race等待一个承诺完成,因此可以将其替换为新的承诺。 这里的技巧是,promise 自动完成后会自动从队列中删除。
,但其状态还是为pending,这里理解为先不执行 执行同步代码4 一轮循环过后,进入第二次宏任务,发现延迟队列中有setTimeout定时器,执行它 首先执行timerStart,然后遇到了resolve..., 0) }, 0) setTimeout(() => { console.log('timer2') }, 0) console.log('start') (2): setTimeout(()...console.log('timer2') }, 0) }); const timer1 = setTimeout(() => { console.log('timer1') Promise.resolve...遇到定时器timer1,将它加入下一次宏任务的延迟列表,标记为宏2,等待执行(先不管里面是什么内容) 执行宏1中的同步代码start 第一次宏任务(宏1)执行完毕,检查第一次的微任务队列(微1),发现有一个...这么多的1,2,3脾气就上来了,不是说好了本篇文章没什么屁话嘛,怎么还是这么多一二三四。 ?,你要理解我的用心良苦啊,我这是帮你把知识点都列举出来,做个总结而已。
console.log('script start');setTimeout(function() { console.log('setTimeout');}, 0);console.log('script...end');以上代码虽然 setTimeout 延时为 0,其实还是异步。...所以 setTimeout 还是会在 script end 之后打印。不同的任务源会被分配到不同的 Task 队列中,任务源可以分为 微任务(microtask) 和 宏任务(macrotask)。...promise1') })}, 0)setTimeout(()=>{ console.log('timer2') Promise.resolve().then(function() {...__proto__; }}setTimeout(fn, 0)多久才执行,Event LoopsetTimeout 按照顺序放到队列里面,然后等待函数调用栈清空之后才开始执行,而这些操作进入队列的顺序
end');以上代码虽然 setTimeout 延时为 0,其实还是异步。...promise1') })}, 0)setTimeout(()=>{ console.log('timer2') Promise.resolve().then(function() {..."); });}, 0);process.nextTick(() => { console.log("nextTick");});// nextTick, timer1, promise1new 一个函数发生了什么构造调用...事件是什么?事件模型?事件是用户操作网页时发生的交互动作,比如 click/move, 事件除了用户触发的动作外,还可以是文档加载,窗口滚动和大小调整。...为什么?
promise规范规定必须要异步的,浏览器实现的promise应该用的是浏览器内部的一些特性(不知道具体是什么),,,但是外部 promise 在 js 层面代码层面上怎么实现异步的呢,答案是:setTimeout...但是为什么可以把回调函数放到未来去注册? 理由是:异步(setTimeout异步或者浏览器自己的实现),确保了then()函数肯定在链条启动前就执行了!...▲ then链条如何保证顺序 test2.png 1、promise1对象有了,显然是执行到setTimeout等待步骤了,状态是pending,timeout完成,立马就是fullfill状态并执行fullfill...我们知道,在你的resovler代码里需要调用resovle函数才能使promise进入到setTimeout等待中。...5、也就是,只有promise1状态完成时,新的promise2才能进入setTimeout等待。 6、依次类推,,一环扣一环,,保证了链条有序执行。
JS引擎一直等待着任务队列中任务的到来,然后加以处理,一个Tab页(renderer进程)中无论什么时候都__只有一个JS线程在运行JS程序__ 同样注意:UI渲染线程与JS引擎线程是互斥的,所以如果JS...console.log('then1'); }); },0) Promise.resolve().then(()=>{ console.log('then2'); Promise.resolve...'); },0) }) 答案:then2 then3 setTimeout1 then1 setTimeout2 首先在题目中出现了es6的promise,他的出现让原来我们理解的__事件环产生了一些不同...('setTimeout') }, 0); // ->4 ?...(function () { console.log('setTimeout') }, 0); // ->4 }) 给个提示,读文件是io操作,io执行之后首先要check,check
(function() { console.log( 'setTimeout'); }, 0) async1(); new Promise (function ( resolve )...( function () { console.log( 'setTimeout' ); }, 0) async1(); new Promise( function ( resolve )...每次宏任务和微任务发生变化,我都会画一个图来表示他们的变化。...直接打印同步代码 console.log('script start') 首先是2个函数声明,虽然有async关键字,但不是调用我们就不看。...然后首先是打印同步代码 console.log('script start')。 ?
还是输出: time is up ⏰ 是后者,因为当一个Promise resolved 后,它就不能再被rejected。...它包含两个参数,一个用于成功执行,另一个则在发生错误时使用。...我们可以使用Promise.all,它通常在启动多个异步任务并发运行并为其结果创建承诺之后使用,以便人们可以等待所有任务完成。...还是2秒? 这个留给你们自己验证咯。...达到限制后,我们使用Promise.race等待一个承诺完成,因此可以将其替换为新的承诺。这里的技巧是,promise 自动完成后会自动从队列中删除。
(function(){ console.log('setTimeout') },0) async1();new Promise(function(resolve){ console.log...注意与setTimeout(fn,0)的区别:setTimeOut(fn(),0)指定某个任务在主线程最早可得的空闲时间执行,也就是说,尽可能早得执行。...(function(){ console.log('setTimeout') },0) async1();new Promise(function(resolve){ console.log...的参数为 promise 对象时直接返回这个 Promise 对象,then 函数在这个 Promise 对象发生改变后立刻执行。...输出'script start'将 setTimeout 里面的回调函数(宏任务)添加到下一轮任务队列。因为这段代码前面没有执行任何的异步操作且等待时间为0s。
回调函数(callback)面试题: 什么是回调函数?回调函数有什么缺点?如何解决回调地狱问题?...如果你在 then 中 使用了 return,那么 return 的值会被 Promise.resolve() 包装Promise.resolve(1) .then(res => { console.log...b先执行,在执行await 10之前变量a还是0,因为await内部实现了generator,generator会保留堆栈中东西,所以这个时候a = 0被保存下来因为await是异步操作,后来的表达式不返回...promise的话,就会包装成Promise.resolve(返回值),然后去执行函数外的同步代码同步代码执行完毕后开始执行异步代码,将保存下来的值拿出来使用,这时候 a = 0 + 10上述解释中提到了...常用定时器面试题: setTimeout,setInterval,requestAnimationFrame 各有什么特点?
回调函数(callback)面试题: 什么是回调函数?回调函数有什么缺点?如何解决回调地狱问题?...如果你在 then 中 使用了 return,那么 return 的值会被 Promise.resolve() 包装,参考 前端进阶面试题详细解答Promise.resolve(1) .then(res...b先执行,在执行await 10之前变量a还是0,因为await内部实现了generator,generator会保留堆栈中东西,所以这个时候a = 0被保存下来因为await是异步操作,后来的表达式不返回...promise的话,就会包装成Promise.resolve(返回值),然后去执行函数外的同步代码同步代码执行完毕后开始执行异步代码,将保存下来的值拿出来使用,这时候 a = 0 + 10上述解释中提到了...常用定时器面试题: setTimeout,setInterval,requestAnimationFrame 各有什么特点?
还是输出: time is up ⏰ 是后者,因为当一个Promise resolved 后,它就不能再被rejected。...它包含两个参数,一个用于成功执行,另一个则在发生错误时使用。...我们可以使用Promise.all,它通常在启动多个异步任务并发运行并为其结果创建承诺之后使用,以便人们可以等待所有任务完成。...还是2秒? 这个留给你们自己验证咯。...58k 声望 10.2k 粉丝 关注作者 0 条评论 得票时间 ? 提交评论 ? 前端小智 前端开发工程师 我不是什么大牛,我其实想做的就是一个传播者。
领取专属 10元无门槛券
手把手带您无忧上云