• ES6-10:Promise


    前端开发因为网络交互的存在,产生了一种最常见的独特场景——异步,即程序执行的过程并非完全按照代码的书写顺序执行。异步编程的解决方法有①回调函数、②事件、③Promise、④观察者对象;
    Promise是ES6提供的一种异步编程的一种解决方案。简单来书就是一个容器,里面存放着某个未来才会结束的事件;从语法角度来说是一个构造函数(对象),可以对各种异步操作进行同样的处理方法。

    1.Promise特点

    • 3种状态:Pending(进行中)、Fulfilled(已成功)、Rejected(已失败);
    • 对象状态不受外界影响:只有异步操作的结果可以决定当前是哪一种状态,任何其他操作都无法改变这个状态;
    • 2种不可逆状态改变:只有两种状态改变①Pending->Fulffiled、②Pending->Rejected;只要两种情况发生任何一种,状态就凝固定型不再改变,即Resolved,任何时候都能且仅能得到这个结果;即使在添加新的对象也立即得到Resolved的结果;

    2. 创建方法

    • 创建:let p=new Promise(function(resolved,reject){});
    var promise=new Promise(function(resolve,rejecte){
    //do somthing here
    if(/*异步操作成功*/){resolve(value)
    }else{reject(value)};
    })
    
    // 案例1 :Promise创建时立即执行
    let promise1=new Promise(function(resolve,reject){
        console.log("Promise is creating...");
        resolve();
    });
    promise1.then(function(){console.log("Promise is resolved !")});
    console.log("Hi Script is Running...");
    
    
    // Promise is creating...
    // Hi Script is Running...
    // Promise is resolved !
    
    // 案例2:Promise返回值可带参数
    var p1=new Promise(function(resolve,reject){});
    var p2=new Promise(function(resolve,reject){
        // do some other things...
        resolve(p1);
    })
    
    // 案例3 :Promise状态定型的会回调函数在本轮事件循环结束时执行
    new Promise((resolve,reject)=>{
        console.log(1);
        resolve(2);
        console.log(3);
    }).then(res=>{
        console.log(res);
    })
    // 1
    // 3
    // 2
    
    // 案例4:显示return语句后的代码不执行
    new Promise(function(resolve,reject){
        console.log(1);
        return resolve(2);
        console.log(3);
    }).then(res=>{
        console.log(res)
    });
    console.log(4)
    // 1
    // 4
    // 2
    
    

    Promise构造函数接受一个函数作为参数,参数函数提供两个参数方法,分别是resolve和reject,这两个方法有JavaScript引擎提供,不用自己部署;Promise实例创建后会立即执行,然后会执行代码中所有的同步操作, 最后会在Promise状态定型后,执行then方法指定的回调函数 ;Promise的回调函数resolve和reject都可带有参数;Promise的回调函数在状态定性后的下一轮事件中执行,即无论状态在何处定型(resolve()),都不影响Promise中其他代码的执行,但显示return语句会影响;

    3. 基本方法

    • Promise.prototype.then(resolveFn,rejectFn?):为Promise实例添加状态改变是的回调函数,返回至为Promise对象;该方法可链式重复调用,将前一个处理结果作为下一个函数的入参,如: promise.then().then()
    • Promise.prototype.catch():指定Promise发生错误时的回调函数,返回值为Promise对象,即Promise.then(null,rejection)的别名;Promise的错误对象具有“冒泡”性质,会一直向后传递,直到被catch或reject捕获;但如果Promise没有使用catch指定错误的处理方法,Promise的错误方法将永远不会传递到外层代码,即不会有任何反应;
    // 案例5:Promise 错误对象冒泡--then过程中的错误会一直传递给最后至被捕获
    let p1=new Promise((resolve,reject)=>{resolve(httpFn)});
    let p2=new Promise((resolve,reject)=>{p1});
    let p3=new Promise((resolve,reject)=>{});
    p3.then(p2).then(otherFn).catch(err=>{errorFn});
    
    // 案例6:Promise的状态一旦定性将无法被改变,即一个Promise实例有且仅有一次改变状态的机会
    let p4=new Promise((resolve,reject)=>{
        resolve('ok');
        throw new Error('test');
    });
    p4.then(res=>{console.log(res)}).catch(err=>{console.log(err)});
    // ok
    
    // 案例7
    let soneFn=function(){
        return new Promise(function(resolve,reject){
            resolve(x+2);//此处应该报错,因为x未声名 
        })
    }
    someFn.then(function(){console.log('Everythings is ok.')});
    // Everything is ok.
    /////因未使用catch捕获Promise异常,报错不会被捕获,也不会传递到外层代码;相反代码正常运行,但会打印错误ReferenceError: x is not defined.
    
    
    • Promise.all(arrLike):将一个具有Iterator接口的数据对象包装成一个新的Promise实例,返回值;

    ①参数arrLike可以是Promise数组、或具有遍历器的数据;如果参数不是Promise数组,则调用Promise.resolve()方法将参数转为Promise实例,在进一步处理;

    ②返回Promise实例的状态:被封装的Promise实例都为Fullfiled状态时,封装返回Promise状态才会变成Fullfied;否则只要有一个为rejected,则会将第一个rejected的实例返回给封装后的Promise,同时,封装后的Promise都会变成rejected;

    let pro1=new Promise.all([p1,p2,p3]);
    let pro2=new Promise.all([1,2,3]); 
    
    • Promise.race(arrLike):将多个具有Iterator接口的数据包装成一个Promise实例;与Promise.all()方法类似;不同之处在于,只要被包装的Promise实例只要有一个率先改变状态,变回将状态结果传递给封装后的Promise对象;
    • Promise.resolve(argu):将一个数据转换成Promise对象;根据传入参数类型的不同处理方法不同,如下:
      ① 参数不存在:直接返回一个状态为Resolved的Promise对象;
      ② Promise对象:返回Promise对象,不做任何处理;
      thenable对象:即一个具有then方法的对象;将这个对象转换成Promise对象并立即执行htneable的then方法;
      ④ 不具有thenable方法或非对象:返回一个新的Promise对象,状态为resolved,结果为参数本身;
    • Promise.reject(argu):返回一个Promise对象,其状态为Rejected;错误结果为整个参数本身;

    5. 与steam事件、Observerble(观察者模式的区别)

    • Promise、Observe都是将异步操作转换成同步操作的实现方式;
    • Promise、Observe都可以进行聚合操作;
    • Promise的状态是不可逆 的,其状态仅有一次改变的机会,一旦改变,状态便定型;结果值需要手动调用才可传递给后续操作
    • Observe的状态是可以多次重复可变的,其状态会根据入参改变并传递给观察者;结果值会主动通知到所有订阅者(后续操作);
  • 相关阅读:
    Windows Server 2003 IIS 使用 Excel.Application
    AutoCAD2008换硬盘后重新激活
    730KII 打印机 Win7 2017年11月更新系统补丁后无法打印
    军训卫生巾鞋垫尺码简易参考
    电阻功率与电流关系
    万用表判断场效应管的好坏
    避免电路接触时火花的产生
    phpexcel如何读和写大于26列的excel
    铅酸蓄电池正确使用与充电管理
    铅酸蓄电池单格最高与最低电压
  • 原文地址:https://www.cnblogs.com/hbzyin/p/8012315.html
Copyright © 2020-2023  润新知