关于promise和async的深刻理解

  1. 本质缘由是JS须要交互,须要引入时间的概念。web

  2. sync=同步,async=不一样步,字面意思跟实际执行状况正好相反。若是没有异步执行,则按照JS的代码一条一条line by line同步执行,执行的逻辑是event loop,即每条代码执行过程当中:若是在main thread上的代码则逐步执行,同步执行顺序参考: developer.mozilla.org/en-US/docs/… 优先级**(stack/script,microtask/promise,task/webapi)**api

  1. 既然JS正常是同步执行,为什么要引入异步的概念?异步的引入是为了“同步”操做流程!

若是要在执行中引入前后的顺序怎么办?好比先获取地理位置再才能计算距离长度。若是同步执行,则会发生错乱。好比地理位置api尚未返回回来,则开始了计算,会出现undefined的错误。promise

let location=getLoaction(api){
    fetch(api);
}
//calCulateDistance
let distance= (location+32)*232/45;
console.log(distance);
复制代码

那么该怎么“同步”这些前后顺序的操做呢?即经过人工控制执行顺序。bash

#一. 以CallBack方法引入前后顺序#异步

fetch(api,(err,location)={
    if(location) {
      let distance= (location+32)*232/45;
      console.log(distance);
    };
})
复制代码

问题是:复杂的逻辑,会引发callback hell,并且把callback函数交由第三方fetch很差。async

#二. 以Promise方法引入前后顺序(须要改写CallBack)函数

getLoaction ()=>{
 return new Promise((resolve, reject) =>{  
    fetch(api,(err,location)={
    if(location) {
     resolve(location)
    }else{
     reject(err)
    };
})
})

复制代码

须要仔细理解的是:代码行碰到promise的时候即开始执行(按照原生的自带的顺序执行stack/microtask/task),轮到microtask的时候,promise已经开始执行,promise是一个已经存在的对象object,这个对象状态在按照内部逻辑更新而已,即pending->fullfilled(reject/resolve)。这个对象是一直存在的。这个对象的内部有一些监听器,then/catch,当对象状态变化时,则触发onThen监听器,其实也是调用咱们传入的CallBack函数而已!这样说来promise本质是方法一CallBack的不一样写法而已!!oop

须要注意的细节是:

  1. Promise的状态在microtask完成后才能改变,若是要获取改变后的值,则须要then,否则promise只是一个带状态的object

  1. 若是修改一下,则发现以下结果,由于microtask运行按照queue来的

3.关于then(其实就是CallBack函数,也叫then handler)返回的问题fetch

A.若是then返回return了ThenReturnedValue,则至关于返回一个Promise.resolve(),这个promise以供下一个then来使用consumeui

B.若是then返回了reject或者throw error,则Promise.reject()

C.若是then返回一个新的Promise,叫NewPromise,则NewPromise

then由于是CallBack,error first callback(实际上是error second callback),因此形式是:.then( resolveCallBackFun,rejectCallBackFun)

#三. 以Async Await方法引入前后顺序(改写Promise)

  1. Async实际上是promise+generator(本质是promise), await就是至关于把promise .then了一下(固然error是经过try catch获取,相似then/catch),跟promise区别是会把后面的所有暂停住,至关于wrap到then里面。如图
function resolveAfter2Seconds() {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve('resolved');
    }, 1000);
  });
}

async function asyncCall() {
  console.log('calling');
  var result = await resolveAfter2Seconds();
  console.log(result);
  console.log('ending');
 }


function promiseCall2() {
  console.log('calling');
  resolveAfter2Seconds().then((result)=>{
     console.log(result);
   }); 
  console.log('ending');
}

asyncCall();//会hold住全部后面的;整个执行顺序仍是正常同步流程stack->microtask->task
> "calling"
> "resolved"
> "ending"

promiseCall2(); //只会hold then里面的;整个执行顺序仍是正常同步流程stack->microtask->task
> "calling"
> "ending"
> "resolved"
复制代码

2.关于async函数func返回的问题, 至关于.then callback, async函数返回也:

A.若是返回value,则async返回Promise.resolve()

B.若是返回NewPromise,则NewPromise

C.若是返回Error,则Promise.reject(),能够经过后续的try/catch捕获

D.若是没有return,则返回Promise.resolve(NULL)

3.async的小技巧IIF

(async () => {
    try {
        var text = await myPromise();
         
    } catch (e) {
       
    }
})();

复制代码

上面的论证被Mozilla再次证实!

重要文献:

jakearchibald.com/2015/tasks-…

developer.mozilla.org/en-US/docs/…

developer.mozilla.org/en-US/docs/…

developer.mozilla.org/en-US/docs/…

相关文章
相关标签/搜索