zoukankan      html  css  js  c++  java
  • js----异步之Promise,Generator,Async

    JS异步之Promise,Generator,Async


    Promise----------解决回调地狱

    解决的问题:回调地狱
    
    Promise规范:
    
    promise有三种状态,等待(pending)、已完成(fulfilled/resolved)、已拒绝(rejected)

    Promise的状态只能从“等待”转到“完成”或者“拒绝”,不能逆向转换,同时“完成”和“拒绝”也不能相互转换. 当返回成功状态时,执行then方法
    当返回失败状态时,执行catch方法

    promise 可进行链式操作

    promise.all()可以将多个Promise实例包装成一个新的Promise实例。
            同时,成功和失败的返回值是不同的,成功的时候返回的是一个结果数组,而失败的时候则返回最先被reject失败状态的值。
    promise.race()

    promise.then(resolve, reject),resolve 和 reject都是可选参数。如果 resolve 或reject 不是函数,其必须被忽略. then 方法必须返回一个 promise 对象.
    1. 使用:

    实例化promise对象需要传入函数(包含两个参数),resolve和reject,内部确定状态.resolve和reject函数可以传入参数在回调函数中使用.
    resolve和reject都是函数,传入的参数在then的回调函数中接收.
    var promise = new Promise(function (resolve, re) {
    
      });
      promise.then(function (val) {
        console.log(val);
      })
    
      function pro(val) {
        var promise = new Promise(function (resolve, reject) {
          if (val) {
            resolve("我是成功状态");
          } else {
            resolve("我是失败状态");
          }
        })
        return promise;
      }
      //返回promise对象
      var op = pro(0);
    //then接收两个函数,分别对应resolve和reject状态的回调,函数中接收实例化时传入的参数.
      op.then((val) => {
        console.log(val);
      }, (val) => {
        console.log(val);
      })
    • Promise回调链:

    promise能够在回调函数里面使用 returnthrow
    所以在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))

    promise.all()

    可以将多个Promise实例包装成一个新的Promise实例。
    同时,成功和失败的返回值是不同的,成功的时候返回的是一个结果数组,而失败的时候则返回最先被reject失败状态的值。
    Promise.all([]).then().catch()获得的成功结果的数组里面的数据顺序和Promise.all接收到的数组顺序是一致的
    只有所有的promise函数都返回成功状态,才会执行then方法
    若有一个promise函数返回失败状态,则执行catch方法

    使用场景:
      比如说一个页面上需要等两个或多个ajax的数据回来以后才正常显示,在此之前只显示loading图标。
      在前端开发请求数据的过程中,偶尔会遇到发送多个请求并根据请求顺序获取和使用数据的场景,使用Promise.all毫无疑问可以解决这个问题。


    let p1 = new Promise((resolve, reject) => { resolve('成功了') }) let p2 = new Promise((resolve, reject) => { resolve('success') }) let p3 = Promse.reject('失败') Promise.all([p1, p2]).then((result) => { console.log(result) //['成功了', 'success'] }).catch((error) => { console.log(error) }) Promise.all([p1,p3,p2]).then((result) => { console.log(result) }).catch((error) => { console.log(error) // 失败了,打出 '失败' })
    Promise.race的使用
    Promse.race就是赛跑的意思,
    意思就是说,Promise.race([p1, p2, p3])里面哪个结果获得的快,就返回那个结果,不管结果本身是成功状态还是失败状态。
    let p1 = new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve('success')
      },1000)
    })
    
    let p2 = new Promise((resolve, reject) => {
      setTimeout(() => {
        reject('failed')
      }, 500)
    })
    
    Promise.race([p1, p2]).then((result) => {
      console.log(result)
    }).catch((error) => {
      console.log(error)  // 打开的是 'failed'
    })

    Generator-------生成器函数,解决异步:

    generator函数使用:
    1、分段执行,可以暂停
    
    2、可以控制阶段和每个阶段的返回值
    3、可以知道是否执行到结尾

    generator和异步控制:

    利用关键字yield,可以把异步操作写在yield语句里面,
    每调用一次next方法,则执行一次yield语句
    如果有return,return完成之后就退出了生成器函数,后面如果还有yield操作,则不再执行

    所以,Generator函数的一个重要实际意义就是用来处理异步操作,改写回调函数。
    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}

    async和异步:-------------通过await解决异步

    用法:
    
    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);//hello word });
    
    
  • 相关阅读:
    Hyper-v: Snapshot merge
    解决Visual Studio 2010 “无法导入以下密钥文件” 错误
    Wix使用整理(二)
    Wix使用整理(一)
    C# 打开指定目录并定位到文件
    常用dos命令
    使用IE9、FireFox与Chrome浏览WPF Browser Application(.XBAP)的方式
    .NET Versioning and Multi-Targeting
    WPF-命令
    在WPF中显示动态GIF
  • 原文地址:https://www.cnblogs.com/SRH151219/p/10399834.html
Copyright © 2011-2022 走看看