Promise, setTimeout

149 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 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)
 })()

image-20220205023230907

后面的数都作为回调内容--微任务