一道经典的前端口试题,你能一眼写出他们的执行后果吗?

async function async1() {            console.log("async1 start");            await  async2();            console.log("async1 end");          }          async  function async2() {            console.log( 'async2');          }          console.log("script start");          setTimeout(function () {            console.log("settimeout");          },0);          async1();          new Promise(function (resolve) {            console.log("promise1");            resolve();          }).then(function () {            console.log("promise2");          });          console.log('script end');

首先第一个问题: JavaScript运行机制是什么?

具体可参考:https://baijiahao.baidu.com/s?id=1615713540466951098&wfr=spider&for=pc

总结几点就是:

  1. JavaScript语言是单线程的,同一个工夫只能做一件事;
  2. 遵循事件循环机制,当JS解析执行时,会被引擎分为两类工作,同步工作(synchronous) 和 异步工作(asynchronous)。对于同步工作来说,会被推到执行栈按程序去执行这些工作。对于异步工作来说,当其能够被执行时,会被放到一个 工作队列(task queue) 里期待JS引擎去执行。当执行栈中的所有同步工作实现后,JS引擎才会去工作队列里查看是否有工作存在,并将工作放到执行栈中去执行,执行完了又会去工作队列里查看是否有曾经能够执行的工作。这种循环查看的机制,就叫做事件循环(Event Loop)。对于工作队列,其实是有更细的分类。其被分为 微工作(microtask)队列 & 宏工作(macrotask)队列。

第二个问题:Promise的原理和运行机制是什么?

古人云:“小人空头支票”,这种“承诺未来会执行”的对象在JavaScript中称为Promise对象。

Promise 是异步编程的一种解决方案,其实是一个构造函数,本人身上有all、reject、resolve这几个办法,原型上有then、catch等办法。

参考:https://blog.csdn.net/qq_37860963/article/details/81539118

这里扩大一个问题:什么是异步呢?

同步就是一件事一件事的执行。只有前一个工作执行结束,能力执行后一个工作。

js代码只能一行一行的执行,不能在同一时间执行多个js代码工作,这就导致如果有一段耗时较长的计算,或者是一个ajax申请等IO操作,如果没有异步的存在,就会呈现用户长时间期待,并且因为当前任务还未实现,所以这时候所有的其余操作都会无响应,这时候就须要异步工作。

参考:https://blog.csdn.net/li123128/article/details/80650256

Promise运行程序总结:

  • promise的构造函数是同步执行,promise.then中的函数是异步执行。
  • 构造函数中的 resolve 或 reject 只有第一次执行无效,屡次调用没有任何作用。promise状态一旦扭转则不能再变。
  • promise 的 .then 或者 .catch 能够被调用屡次,但这里 Promise 构造函数只执行一次。或者说 promise 外部状态一经扭转,并且有了一个值,那么后续每次调用 .then 或者 .catch 都会间接拿到该值。
  • 如果在一个then()中没有返回一个新的promise,则 return 什么下一个then就承受什么,如果then中没有return,则默认return的是 undefined.
  • then()的嵌套会先将外部的then()执行结束再继续执行内部的then();
  • catch和then的连用,如果每一步都有可能呈现谬误,那么就可能呈现catch前面接上then的状况。如果在catch中也抛出了谬误,则前面的then的第一个函数不会执行,因为返回的 promise状态曾经为rejected了

第三个问题:async、await执行程序?

什么是Async/Await?

  • async/await是写异步代码的新形式,以前的办法有回调函数Promise
  • async/await是基于Promise实现的,它不能用于一般的回调函数。
  • async/await与Promise一样,是非阻塞的。
  • async/await使得异步代码看起来像同步代码,这正是它的魔力所在。
  • await关键字只能用在aync定义的函数内。async函数会隐式地返回一个promise,该promise的reosolve值就是函数return的值。

执行程序:

应用 async 定义的函数,当它被调用时,它返回的其实是一个 Promise 对象。(当这个 async 函数返回一个值时,Promise 的 resolve 办法会负责传递这个值;当 async 函数抛出异样时,Promise 的 reject 办法也会传递这个异样值。)

await是一个让出线程的标记。await前面的函数会先执行一遍,而后就会跳出整个async函数来执行前面js栈的代码,等本轮事件循环执行完了之后又会跳回到async函数中期待await前面表达式的返回值,如果返回值为非promise则继续执行async函数前面的代码,否则将返回的promise放入promise队列。

参考:https://segmentfault.com/a/1190000011296839

问题四:setTimeout的执行?

setTimeout和Promise一样也是异步的

宏工作个别包含:整体代码script,setTimeout,setInterval。

微工作:Promise,process.nextTick

微工作执行优先级高于宏工作,所以Promise比setTimeout优先执行。
了解了以上4个问题,那么这道口试题也就容易了解了

最终后果: