今天看了一道经典前端题,看完之后感觉颇有收获,愿与君共勉;
`先上题:
async function foo() {
console.log('f00');
};
async function bar() {
console.log('bar start');
await foo();
console.log('bar end')
};
console.log('script start');
setTimeout(function() {
console.log('settimeout');
}, 0);
bar();
new Promise(function(resolve) {
console.log('promise executor');
resolve();
}).then(function() {
console.log('promise then');
})
console.log('script end');`
首先,我们来聊一下javascript的运行原理;
JavaScript是一个单线程的,程序运行自上而下,且遵循事件循环机制(event Loop),程序运行时分为同步任务和异步任务,同步任务就是事情一件一件干,一个执行任务完成再执行下一个,这就需要等待时间,而异步就是将执行任务放入执行队列中,当前一个结束,再到执行队列中找下一个执行任务,这样循环往复,就形成了event Loop。简单来说。同步就是你在买奶茶时前面一个人拿到奶茶,你才能买,而异步就是你已经付过钱了,先到一旁等待制作奶茶完成,商家继续下一个买家买票。
然后我们来聊下这几种异步方式。
1,promise
promise的状态有三种分别是pending(初始化),fulfilled(已完成),rejected(已失败);状态改变也只有两种可能
pending到fulfilled:执行成功后执行resolved函数,既.then后的函数;
pending到rejected:执行成功后执行rejected函数,既.catch后的函数;
promise的状态一旦改变便不再发生变化,then和catch可多次调用,then执行结束后下一个then接到的参数是上一个then return的值;
2,async和await
async/await是异步执行的新方式,它是基于promise实现的,且await只能写在async里面,async会返回promise的对象,成功时resolve的return的值,失败时reject的return的值,而await是让出线程的一个标志,当遇到await时则跳出整个async函数先执行async函数之外的函数,执行完成后再跳回async函数。
3,setTimeout
异步任务又分为微任务和宏任务,
微任务:promise,process.$nextick
宏任务:setTimeout,setInterval,script
而微任务的优先级要高于宏任务
基于以上,我们来看这道题,它的结果就是程序自上而下先运行,遇到await跳出async执行,再执行promise然后最后执行settimeout,结果就是

浙公网安备 33010602011771号