携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第20天,点击查看活动详情
11.1. setTimeout
console.log('script start') //1. 打印 script start
setTimeout(function(){
console.log('settimeout') // 4. 打印 settimeout
}) // 2. 调用 setTimeout 函数,并定义其完成后执行的回调函数
console.log('script end') //3. 打印 script end
// 输出顺序:script start->script end->settimeout
11.2. Promise
Promise本身是同步的立即执行函数, 当在executor中执行resolve或者reject的时候, 此时是异步操作, 会先执行then/catch等,当主栈完成后,才会去调用resolve/reject中存放的方法执行,打印p的时候,是打印的返回结果,一个Promise实例。
console.log('script start')
let promise1 = new Promise(function (resolve) {
console.log('promise1')
resolve()
console.log('promise1 end')
}).then(function () {
console.log('promise2')
})
setTimeout(function(){
console.log('settimeout')
})
console.log('script end')
// 输出顺序: script start->promise1->promise1 end->script end->promise2->settimeout
当JS主线程执行到Promise对象时:
- promise1.then() 的回调就是一个 task
- promise1 是 resolved或rejected: 那这个 task 就会放入当前事件循环回合的 microtask queue(微任务队列)
- promise1 是 pending: 这个 task 就会放入 事件循环的未来的某个(可能下一个)回合的 microtask queue 中
- setTimeout 的回调也是个 task ,它会被放入 macrotask queue(宏任务队列) 即使是 0ms 的情况
11.3. async/await
好用的语法糖
异步回调 callback hell
promise then catch 链式调用, 也是基于回调函数
async/await 同步语法, 彻底消灭回调函数
async function async1(){
console.log('async1 start');
await async2();
console.log('async1 end')
}
async function async2(){
console.log('async2')
}
console.log('script start');
async1();
console.log('script end')
// 输出顺序:script start->async1 start->async2->script end->async1 end
async 函数返回一个 Promise 对象,当函数执行的时候,一旦遇到 await 就会先返回,等到触发的异步操作完成,再执行函数体内后面的语句。可以理解为,是让出了线程,跳出了 async 函数体。
await的含义为等待,也就是 async 函数需要等待await后的函数执行完成并且有了返回结果(Promise对象)之后,才能继续执行下面的代码。await通过返回一个Promise对象来实现同步的效果。
function loadImg(src) {
//pending
const p = new Promise(
(resolve,reject)=>{
const img =document.createElement('img')
img.onload=()=>{
resolve(img)//resolve
}
img.onerror=()=>{
const err = new Error('input failly ${src}')
reject(err)//rejected
}
img.src = src
}
)
return p
}
const src1 = 'https://s.cn.bing.net/th?id=ODLSF.0b3ab3c6-5a37-48a2-9392-fd2793d6c3ba&w=16&h=16&o=6&pid=1.2s.cn.bing.net/th?id=ODLSF.0b3ab3c6-5a37-48a2-9392-fd2793d6c3ba&w=16&h=16&o=6&pid=1.2'
const src2 = 'https://s.cn.bing.net/th?id=ODLSF.fe8ea22b-db88-4e39-ab8b-eead65c2bb26&w=16&h=16&o=6&pid=1.2'
async function loadImg1(){
const img1 = await loadImg(src1)
return img1
}
async function loadImg2(){
const img2 = await loadImg(src2)
return img2
}
!(async function(){
const img1 = await loadImg(src1)
console.log(img1.height
,img1.width)
const img2 = await loadImg(src2)
console.log(img2.height
,img2.width)
})()
后面的数都作为回调内容--微任务