Promise

1 基础

1.1 三种状态

pending——进行中
fulfilled——已完成
rejected——已失败
只有异步操作的结果才可以决定当前是哪一种状态,其他任何操作无法改变这个状态

1.2 一旦状态改变,就不会再变

Promise对象的状态改变,只有两种可能:从Pending变为Resolved和从Pending变为Rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果。如果改变已经发生了,你再对Promise对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。

1.3 缺点

  1. 对带逻辑的异步操作麻烦
  2. 无法取消Promise,一旦新建它就会立即执行,无法中途取消
  3. 如果不设置回调函数,Promise内部抛出的错误,不会反应到外部
  4. 当处于Pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)

2 基本用法

2.1 生成实例

new Promise((resolve, reject) => {
  // ?做一些异步操作,最终会调用下面两者之一:
  //
  //   resolve(someValue); // fulfilled
  // ?或
  //   reject( err ---> "failure reason"); // rejected
});

resolve 函数作用:在异步操作成功时,将结果作为参数传递出去
reject 函数作用:在异步操作失败时,将异步操作报出的错误作为参数传递出去

2.2 then()

promise.then ( 操作成功时的回调函数 , 操作失败时的回调函数 );
成功:function ( someValue —> Promise对象传出的值 ) { … }
失败:function ( err —> Promise对象传出的值 ) { … } ( 可选 一般用 catch 方法)
链式then
若前一个then方法返回的是新的Promise实例,则后面可以再调用一个then方法

2.3 catch()

相当于 .then( null, rejection )
指定发生错误时的回调函数
特性:

  1. promise对象错误具有冒泡性,总是会被后面的 catch 捕获,所以catch必须
  2. catch 方法返回 Promise 对象,后面可以再用 then()

2.4 all()

Promise.all( [p1, p2, p3] ) 接受一个数组作为参数

  1. p1, p2, p3 都为 fulfilled 时 p 才为 fulfilled,返回值:组成一个数组返回给回调函数
  2. p1, p2, p3 其中有一个为 rejected, p就为rejected,返回值:第一个被rejected的实例的返回值,被返回给回调函数

3 实例

4 常见Promise面试题

  1. 了解 Promise 吗?
    用同步的写法写异步的操作,来解决回调地狱的问题

  2. Promise 解决的痛点是什么?
    痛点:回调地狱

  3. Promise 解决的痛点还有其他方法可以解决吗?如果有,请列举。
    async / await

  4. Promise 如何使用?
    初始化Promise对象,用then方法注册回调函数,用catch方法注册异常处理函数

  5. Promise 常用的方法有哪些?它们的作用是什么?
    then()——注册成功时的回调函数
    catch()——注册失败时的回调函数

  6. Promise 在事件循环中的执行过程是怎样的?

  7. Promise 的业界实现都有哪些?
    Q、bluebird(号称运行最快的类库)

  8. 能不能手写一个 Promise 的 polyfill。


例子

异步加载图片

function loadImageAsync(url) {
  return new Promise(function(resolve, reject) {
    var image = new Image();

    image.onload = function() {
      resolve(image);
    };

    image.onerror = function() {
      reject(new Error('Could not load image at ' + url));
    };

    image.src = url;
  });
}

上面代码中,使用Promise包装了一个图片加载的异步操作。如果加载成功,就调用resolve方法,否则就调用reject方法

Promise 对象实现 Ajax 操作

var getJSON = function(url) {
  var promise = new Promise(function(resolve, reject){
    var client = new XMLHttpRequest();
    client.open("GET", url);
    client.onreadystatechange = handler;
    client.responseType = "json";
    client.setRequestHeader("Accept", "application/json");
    client.send();

    function handler() {
      if (this.readyState !== 4) {
        return;
      }
      if (this.status === 200) {
        resolve(this.response);
      } else {
        reject(new Error(this.statusText));
      }
    };
  });

  return promise;
};

getJSON("/posts.json").then(function(json) {
  console.log('Contents: ' + json);
}, function(error) {
  console.error('出错了', error);
});

上面代码中,getJSON是对XMLHttpRequest对象的封装,用于发出一个针对JSON数据的HTTP请求,并且返回一个Promise对象。需要注意的是,在getJSON内部,resolve函数和reject函数调用时,都带有参数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值