美文网首页js css htmlJavaScript理论知识
26:promise+Generator+Async 的使用

26:promise+Generator+Async 的使用

作者: 小小前端搬运工 | 来源:发表于2022-06-02 21:28 被阅读0次

    Promise

    解决的问题:回调地狱

    Promise 规范:

    promise 有三种状态,等待(pending)、已完成(fulfilled/resolved)、已拒绝(rejected)

    .Promise 的状态只能从“等待”转到“完成”或者“拒绝”,不能逆向转换,同时“完成”和 “拒绝”也不能相互转换.

    promise 必须提供一个 then 方法以访问其当前值、终值和据因。promise.then(resolve, reject),resolve 和 reject 都是可选参数。如果 resolve 或 reject 不是函数,其必须被忽略.

    then 方法必须返回一个 promise 对象.

    使用:

    实例化 promise 对象需要传入函数(包含两个参数),resolve 和 reject,内部确定状态.resolve 和 reject 函数可以传入参数在回调函数中使用.

    resolve 和 reject 都是函数,传入的参数在 then 的回调函数中接收.

    var promise = new Promise(function(resolve, reject) { 
    
      setTimeout(function(){ 
    
        resolve('好哈哈哈哈'); 
    
      }); 
    
    }); 
    
    promise.then(function(val){ 
    
      console.log(val) 
    
    })
    
    

    then 接收两个函数,分别对应 resolve 和 reject 状态的回调,函数中接收实例化时传入的参数.

    promise.then(val=>{ 
    
      //resolved 
    
    },reason=>{ 
    
      //rejected 
    
    })
    

    catch 相当于.then(null, rejection)

    当 then 中没有传入 rejection 时,错误会冒泡进入 catch 函数中,若传入了 rejection,则错误会被 rejection 捕获,而且不会进入 catch.此外,then 中的回调函数中发生的错误只会在下一级的 then 中被捕获,不会影响该 promise 的状态.

    new Promise((resolve,reject)=>{ 
    
      throw new Error('错误') 
    
    }).then(null,(err)=>{ 
    
      console.log(err,1);//此处捕获 
    
    }).catch((err)=>{ 
    
      console.log(err,2); 
    
    }); 
    
    // 对比 
    
    new Promise((resolve,reject)=>{ 
    
      throw new Error('错误') 
    
    }).then(null,null).catch((err)=>{ 
    
      console.log(err,2);//此处捕获 
    
    }); 
    
    // 错误示例 
    
    new Promise((resolve,reject)=>{ 
    
      resolve('正常'); 
    
    }).then((val)=>{ 
    
      throw new Error('回调函数中错误') 
    
    },(err)=>{ 
    
      console.log(err,1); 
    
    }).then(null,(err)=>{ 
    
      console.log(err,2);//此处捕获,也可用 catch 
    
    }); 
    

    两者不等价的情况:

    此时,catch 捕获的并不是 p1 的错误,而是 p2 的错误,

    p1().then(res=>{ 
    
      return p2()//p2 返回一个 promise 对象 
    
    }).catch(err=> console.log(err)) 
    

    一个错误捕获的错误用例:

    该函数调用中即使发生了错误依然会进入then 中的resolve 的回调函数,因为函数 p1中实例化 promise 对象时已经调用了 catch,若发生错误会进入 catch 中,此时会返回一个新的 promise,因此即使发生错误依然会进入 p1 函数的 then 链中的 resolve 回调函数.

    function p1(val){ 
    
      return new Promise((resolve,reject)=>{ 
    
        if(val){ 
    
          var len = val.length;//传入 null 会发生错误,进入 catch 捕获错 
    
          resolve(len); 
    
        }else{ 
    
          reject(); 
    
        }
    
    }).catch((err)=>{ 
    
      console.log(err) 
    
    })
    
    };
    
    p1(null).then((len)=>{ 
    
      console.log(len,'resolved'); 
    
    },()=>{ 
    
      console.log('rejected'); 
    
    }).catch((err)=>{ 
    
      console.log(err,'catch'); 
    
    })
    

    Promise 回调链:

    promise 能够在回调函数里面使用 return 和 throw, 所以在 then 中可以 return 出一个 promise 对象或其他值,也可以 throw 出一个错误对象,但如果没有 return,将默认返回 undefined,那么后面的 then 中的回调参数接收到的将是 undefined.

    function p1(val){ 
    
      return new Promise((resolve,reject)=>{ 
    
          val==1?resolve(1):reject() 
    
      })
    
    };
    
    function p2(val){ 
    
      return new Promise((resolve,reject)=>{ 
    
          val==2?resolve(2):reject(); 
    
      })
    
    };
    
    let promimse = new Promise(function(resolve,reject){ 
    
      resolve(1) 
    
    })
    
    .then(function(data1) { 
    
      return p1(data1)//如果去掉 return,则返回 undefined 而不是 p1 的返回值,会导致报错 
    
    })
    
    .then(function(data2){ 
    
      return p2(data2+1) 
    
    })
    
    .then(res=>console.log(res)) 
    

    Generator 函数:

    generator 函数使用:

    1、分段执行,可以暂停

    2、可以控制阶段和每个阶段的返回值

    3、可以知道是否执行到结尾

    function* g() { 
    
      var o = 1; 
    
      yield o++; 
    
      yield o++; 
    
    }
    
    var gen = g(); 
    
    console.log(gen.next()); // Object {value: 1, done: false} 
    
    var xxx = g(); 
    
    console.log(gen.next()); // Object {value: 2, done: false} 
    
    console.log(xxx.next()); // Object {value: 1, done: false} 
    
    console.log(gen.next()); // Object {value: undefined, done: true} 
    

    generator 和异步控制:

    利用 Generator 函数的暂停执行的效果,可以把异步操作写在 yield 语句里面,等到调用 next 方法时再往后执行。这实际上等同于不需要写回调函数了,因为异步操作的后续操作可以放在 yield 语句下面,反正要等到调用 next 方法时再执行。所以,Generator 函数的一个重要实际意义就是用来处理异步操作,改写回调函数。

    async 和异步:

    用法:

    async 表示这是一个 async 函数,await 只能用在这个函数里面。

    await 表示在这里等待异步操作返回结果,再继续执行。

    await 后一般是一个 promise 对象

    示例:async 用于定义一个异步函数,该函数返回一个 Promise。

    如果 async 函数返回的是一个同步的值,这个值将被包装成一个理解 resolve 的 Promise, 等同于 return Promise.resolve(value)。

    await 用于一个异步操作之前,表示要“等待”这个异步操作的返回值。await 也可以用于一个同步的值。

    let timer = async function timer(){ 
    
    return new Promise((resolve,reject) => { 
    
    setTimeout(() => { 
    
    resolve('500'); 
    
    },500); 
    
    }); 
    
    }
    
    timer().then(result => { 
    
    console.log(result); //500 
    
    }).catch(err => { 
    
    console.log(err.message); 
    
    }); 
    
    //返回一个同步的值 
    
    let sayHi = async function sayHi(){ 
    
    let hi = await 'hello world'; 
    
    return hi; //等同于 return Promise.resolve(hi); 
    
    }
    
    sayHi().then(result => { 
    
    console.log(result); 
    
    }); 
    

    相关文章

      网友评论

        本文标题:26:promise+Generator+Async 的使用

        本文链接:https://www.haomeiwen.com/subject/osxcmrtx.html