黑马程序员技术交流社区

标题: 【上海校区】浅析setTimeout与Promise [打印本页]

作者: 不二晨    时间: 2018-8-13 09:35
标题: 【上海校区】浅析setTimeout与Promise
前言我们先看一到常见的前端面试题:
var p1 = new Promise(function(resolve, reject){    resolve(1);})setTimeout(function(){  console.log("will be executed at the top of the next Event Loop");},0)p1.then(function(value){  console.log("p1 fulfilled");})setTimeout(function(){  console.log("will be executed at the bottom of the next Event Loop");},0)复制代码上例代码执行输出顺序如何?这道题也是本文创作的源泉,其答案是:
p1 fulfilledwill be executed at the top of the next Event Loopwill be executed at the bottom of the next Event Loop复制代码接下来展开解释输出结果原因,看完本文应该能了解setTimeout和Promise的区别。
事件循环事件循环相关详细内容在JavaScript异步编程一文已经介绍过,本文不再赘述,进行一些补充和总结:


可执行代码思考一下,JavaScript代码是如何执行的呢?是一行一行代码执行的吗?当然不是,JavaScript 引擎一块一块地解析,执行JavaScript代码,而非一行一行进行。在解析,执行代码块时,会需要有一个前期工作,如变量/函数提升,定义变量/函数。这里所说的代码块,通常称作可执行代码(execuable code),通常包括全局代码,函数代码,eval执行代码。而所做的前期工作就是创建执行上下文(execution context)。
执行上下文栈每当JavaScript引擎开始执行应用程序时,都会创建一个执行上下文栈(后进先出),用以管理执行上下文。在执行一段可执行代码时,会创建一个执行上下文,然后将其压入栈,执行完毕便将该上下文退栈。
function funA() {    console.log('funA')}function funB() {    fun3A();}function funC() {    funB();}funC();复制代码ECStack.push(<funC> functionContext);// funC中调用funB,需创建funB执行上下文,入栈ECStack.push(<funB> functionContext);// funB内调用funA,入栈上下文ECStack.push(<funA> functionContext);// funA执行完毕,退栈ECStack.pop();// funB执行完毕,退栈ECStack.pop();// funC执行完毕,退栈ECStack.pop();// javascript继续执行后续代码复制代码另外,所有的代码都是从全局环境开始执行,所以,必然栈底是全局执行上下文。
异步任务回顾JavaScript事件循环并发模型,我们了解了setTimeout和Promise调用的都是异步任务,这一点是它们共同之处,也即都是通过任务队列进行管理/调度。那么它们有什么区别吗?下文继续介绍。
任务队列前文已经介绍了任务队列的基础内容和机制,可选择查看,本文对任务队列进行拓展介绍。JavaScript通过任务队列管理所有异步任务,而任务队列还可以细分为MacroTask Queue和MicoTask Queue两类。
MacroTask QueueMacroTask Queue(宏任务队列)主要包括setTimeout, setInterval, setImmediate, requestAnimationFrame, NodeJS中的`I/O等。
MicroTask QueueMicroTask Queue(微任务队列)主要包括两类:
MacroTask和MicroTaskJavaScript将异步任务分为MacroTask和MicroTask,那么它们区别何在呢?


回顾介绍基本结束,我们以一个题目再次回顾一下内容:
setTimeout(function(){  console.log("will be executed at the top of the next Event Loop")},0)var p1 = new Promise(function(resolve, reject){    setTimeout(() => { resolve(1); }, 0);});setTimeout(function(){    console.log("will be executed at the bottom of the next Event Loop")},0)for (var i = 0; i < 100; i++) {    (function(j){        p1.then(function(value){           console.log("promise then - " + j)        });    })(i)}复制代码代码输出结果是什么呢?快点确认一下吧:
will be executed at the top of the next Event Looppromise then - 0promise then - 1promise then - 2...promise then - 99will be executed at the bottom of the next Event Loop复制代码

【转载】
链接:https://juejin.im/post/5b7057b251882561381e69bf




作者: 小影姐姐    时间: 2018-8-13 10:30

作者: 梦缠绕的时候    时间: 2018-8-16 16:14

作者: 不二晨    时间: 2018-8-16 17:19
奈斯




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2