promise

promise

概念:简单说promise就是一个容器,里面保存着某个未来才会结束的事件的结果,它可以获取异步操作的信息

三种状态(只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态,即—不受外界影响和不可逆):

  • Pending(进行中)
  • Resolved(已完成,又称 Fulfilled)
  • Rejected(已失败)
  //注意:promise是全部都成功时才成功,一个失败即失败
  var p = new Promise(function(success,error){
    //做一些异步操作
    ajax / setTimeout

    //成功的时候,执行的函数
    success();

    //失败的时候,执行的函数
    error();
  })

  //定义成功和失败的状态要执行的代码
  p.then(function(value){
    console.log(value);   //成功时调用
  },function(value){
    console.log(value);   //失败时调用
  })

传统的回调异步操作的缺点以及promise如何解决异步操作?

  • 调用回调过早

    • 对promise而言,即使是立即完成的promise也无法被同步观测到,也就是说一个promise调用then()的时候,即使这个promise已经决议了,提供给then的回调也总会被异步调用
  • 调用回调过晚(或没有被调用)

    • 对于一个promise对象注册每一个观察回调都是相对独立、互不相扰的。而promise对象调用都会被自动调用resolved()和reject()时,每个注册的观察回调也会被自动调用,所以这些观察回调的任意一个都无法影响或延误对其他回调的调用
    • 而回调未调用,正常情况下,没有任何东西可以阻止promise想你通知它的决议,即使你的 js代码报错了,一会通过异常回调来获取到。如果Promise 永远不被决议的话, Promise 本身已提供了静态的抽象机制来作为解决方案
      调用回调次数过少或过多
      promise 的定义方式使得它只能被决议一次。即使代码中出现多次决议,这个 Promise 也会接受第一次决议,并会忽略掉其他任何后续调用。所以任何通过 then() 注册的回调只会被调用一次
  • 未能传递所需的环境和参数

    • 凡是被决议的值,都会被传递到观察回调中,如果没有显示的决议也会传递一个 undefined 给观察回调。需要主要的是,Promise 只允许传一个决意值,其他值会被默默忽略掉
  • 吞掉可能出现的错误和异步

    • 如果在创建 Promise 时,存在 JS 代码错误,会直接导致该 Promise 的拒绝决议,那么你可以通过 reject() 来获取异常,代码中的任何异常都不会吞掉。

Promise.all( ) 和 Promise.race( ) 的区别

  • all会将传入的数组中的所有 Promise 全部决议以后,将决议值以数组的形式传入到观察回调中,任何一个 Promise决议为拒绝,那么就会调用拒绝回调
  • 传递空数组时,all会立即决议,决议结果是 fullfilled, 值是 undefined
  • race会将传入的数组中的所有 promise 中第一个决议的决议值传递给观察回调,即使决议结果是拒绝的。
  • 传递空数组时,race会永远都不决议,程序卡死。。。

Promise是如何捕获异常的?与传统的 try / catch 相比有什么优势?

传统的 try / catch 捕获异常方式是无法捕获异步的异常的,代码如下

try{
    setTimeout(function(){
        undefined();   // undefined 不是一个方法,会抛出异常
    }500)
} catch(err){
    console.log(err)
}
  try{
    //有可能报错的语句
    documnt.write("hello");
  }catch(eve){    //try中的错误提示,ReferenceError: documnt is not defined
    at promise.html:33
    //报错之后,会执行这里的代码
    console.log(eve);
  }
  console.log("world");		//world

而对于Promise对象来说,构造Promise实例时的代码如果出错,则会被认为是一个拒绝的决议,并会想观察回调中传递异常信息。所以即使是一个异步的请求,Promise也是可以捕获异常的,此外,Promise还可以通过 catch回调来捕获回调中的异常。

例:

  var url1 = "xxxxxxxxxxxxx";
  var url2 = "xxxxxxxxxxxxx";
  var url3 = "xxxxxxxxxxxxx";

  var p1 = ajax(url1);
  var p2 = ajax(url2);
  var p3 = ajax(url3);

  var p = Promise.all([p1,p2,p3]);
  p.then(function(res){
    console.log(res);
  },function(res){
    console.log(res);
  })

  function ajax(url){
    var p = Promise(function(success,error){
      var ajax = new XMLHttpRequest();
      ajax.open("post",url,true);
      ajax.onreadystatechange = function(){
        if(ajax.readyState == 4 && ajax.status == 200){
          success(ajax.responseText);
        }else if(ajax.readyState == 4 && ajax.status != 200){
          error(ajax.status);
        }  
      }
      ajax.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
      ajax.send("user=admin&pass=123");
    });
    return p;
  }

如有侵权,请联系删除,谢谢

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值