微任务与宏任务
一、前情提要:
1、js是单线程语言;
2、**宏任务(Macrotasks):**js同步执行的代码块,setTimeout、setInterval、XMLHttprequest、setImmediate、I/O、UI rendering等;
3、**微任务(Microtasks):**promise、process.nextTick(node环境)、Object.observe, MutationObserver等。 (
微任务比宏任务要牛逼一点
)。
二、事件轮询(2、3、4、5、6执行的过程就是轮询)
浏览器执行的顺序:
(1)执行主代码块,这个主代码块也是宏任务
(2)若遇到Promise,把then之后的内容放进微任务队列
(3)遇到setTimeout,把他放到宏任务里面
(4)一次宏任务执行完成,检查微任务队列有无任务
(5)有的话执行所有微任务
(6)执行完毕后,开始下一次宏任务。
三、promise
这个async声明的异步函数把return后面直接量通过Promise.resolve()返回Promise对象,所以如果这个最外层没有用await调用的话,是可以用原来then链的方式来调用的:
async function testAsy(){ return 'hello world' } let result = testAsy() console.log(result) result.then(v=>{ console.log(v) //hello world })
联想一下Promise特点——异步无等待,所以当没有await语句执行async函数,它就会立即执行,返回一个Promise对象,非阻塞,与普通的Promise对象函数一致。
重点就在await,它等待什么呢?
按照语法说明,await等待的是一个Promise对象,或者是其他值(也就是说可以等待任何值),如果等待的是Promise对象,则返回Promise的处理结果;如果是其他值,则返回该值本身。并且await会暂停当前async function的执行,等待Promise的处理完成。若Promise正常处理(fulfillded),其将回调的resolve函数参数作为await表达式的值,继续执行async function;若Promise处理异常(rejected),await表达式会把Promise异常原因抛出;另外如果await操作符后面的表达式不是一个Promise对象,则返回该值本身。
四、Genorator函数
特点:
1、function后面有个小*,这个地方有两种写法,没啥太大区别;
function* doSomething(){} function *doSomething(){}
2、函数里面会有一个yield,把函数截成不同的状态;
一个yield可以截成两个状态,也就需要两个next()触发;
3、Generator函数自己不会执行,而是会返回一个遍历器对象;
4、遍历器对象会通过.next()方法依次调用各个状态。
例子
总结
第一个next()是用来启动Generator函数的,传值会被忽略,没用
yield的用法和return比较像,你可以当做return来用,如果yield后没值,return undefined
最后一个next()函数,得到的是函数return的值,如果没有,也是undefined
五、async与await
function f() { return new Promise(resolve =>{ resolve('hhh') }) } async function doSomething1(){ let x = await f() } doSomething1() 打印结果: hhh
特点:
1、函数前面会加一个async修饰符,来证明这个函数是一个异步函数;
2、await 是个运算符,用于组成表达式,它会阻塞后面的代码
3、await 如果等到的是 Promise 对象,则得到其 resolve值。
async function doSomething1(){ let x = await 'hhh' return x } console.log(doSomething1()) doSomething1().then(res => { console.log(res) }) 打印结果: Promise {<pending>} hhh
特点:
1、async返回的是一个promise对象,函数内部 return 返回的值,会成为 then 方法回调函数的参数;
2、await如果等到的不是promise对象,就得到一个表达式的运算结果。
友情链接:https://www.cnblogs.com/youma/p/10475214.html