从promise到async/await

一、callback回调函数

如果一个函数作为另一个函数的参数,则这个函数就是回调函数

  • 同步回调
    • 在函数结束之前执行回调函数
  • 异步回调
    • 在函数结束之后执行回调函数

绝大多数回调函数采用异步的方式

二、Promise

① Promise的executor 函数

executor控制promise的状态padding、reject、resolve(fulfilled)

  • executor返回值是resolve,则调用than中的回调函数,resolve中的参数会传给遇到的第一个than中的回调函数

  • executor的返回值是reject,则调用catch中的回调函数,reject中的参数会传给遇到的第一个catch中的回调函数;

  • executor没有返回resolve或者reject,则promise状态为padding,则不会触发回调

② promise的than/catch方法

than和catch的结果也是一个promise

  • 如果你在than/catch中throw,则返回的promise的状态是reject

  • 如果你在than/catch中return,则返回的promise的状态是resolve

  • 如果你return了一个新的promise,则会根据这个新的promise的状态来返回

③ promise.all()

  • 此方法接收的参数是一个数组

  • 数组里面有多个状态为reject或者resolve的promise

  • 当数组中所有的promise都resolve,则找than方法,否则找catch方法

  • 如果是resolve,则than方法接收到的是一个数组

  • 如果是reject,则catch默认只接收第一个reject中的参数(err)。

  • 如果想要所有的err,则需要把数组中promise的返回值额外再存起来

三、async/await

async/await是异步编程的终极解决方案,但是只有在理解promise的基础上才能更好的理解async/await

① async

async只不过是promise的一个语法糖而已

  • async方法默认是一个padding的promise对象
  • return时会改变promise的状态为resolve,并把return的值传递给resolve
  • throw时会改变promise的状态为reject,并把throw的值传递给reject

② await

await代替了promise中then方法的作用,使async/await体系中不需要than。但是await和than无关。

  • await可以使async方法不能向下执行,直到await后面的promise回调函数调用完毕

  • 若await后面的promise返回resolve,则调用下一个await

  • 若await后面的promise返回reject,则直接进入catch

  • try-catch获取await里面返回的错误

需要使用并行的promise,则可以结合promise.all()来解决

四、async/await的原理

① 协程

一个线程上可以存在多个协程,但是在线程上同时只能执行一个协程。当前执行的是 A 协程,要启动 B 协程,那么 A 协程就需要将线程的控制权交给 B 协程,这就体现在 A 协程暂停执行,B 协程恢复执行;同样,也可以从 B 协程中启动 A 协程。通常,如果从 A 协程启动 B 协程,我们就把 A 协程称为 B 协程的父协程。

② example

async function foo() {
     
    console.log(1)
    let a = await 100
    console.log(a)
    console.log(2)
}
console.log(0)
foo()
console.log(3)

以下是代码执行的步骤:

  • console.log(0)

  • foo()

    • 遇到async的foo函数,则创建一个协程,此协程控制了当前线程

    • 在此协程上执行代码:则console.log(1)

    • 然后碰到了await:new了一个promise并resolve(100),然后把than中回调函数放到微任务队列里面。尽管在这个例子里面没有实现than,也就是回调函数里面什么都没有做

      //100会作为实参传给value
      promise_.then((value)=>{
               
          return value
      })
      
    • 然后线程控制权转交给父协程。

    • 这个时候foo函数是不会执行的,因为await还没有结束他的promise,除非他的微任务执行完毕

  • 在父协程上执行代码:console.log(3)

  • 执行微任务

  • 微任务执行完毕,await有了返回值,则foo的协程会控制线程

    • console.log(a)//100
    • console.log(3)

你可能感兴趣的:(浏览器工作原理,前端,javascript)