Promise特性总结

这里写图片描述

Promise 对象代表着一个还未完成,但预期将来会完成的操作,该新特性属于 ECMAScript 2015(ES6)规范。
使用 Promise 对象,可以十分方便的摆脱层层嵌套的异步操作回调函数,而以同步操作的流程书写代码。
Promise 对象主要具有以下两个特点:

  1. Promise 对象的状态只受构造函数内的同步或者一步操作影响,其他外部操作无法改变 Promise 对象的状态。
  2. Promise 对象的状态改变,只会从 pending 变为 resolved 或者从 pending 变为rejected,状态改变后不再会发生改变。

浏览器兼容性

|Chrome |Edge |Firefox |IE |Opera |Safari|
|32.0 |Yes |29.0 |未实现 |19 |7.1|

Promise Constructor

Promise 对象构造器接受一个带有 resolvereject 两个参数的函数,resolve 用于处理执行成功的场景,reject 用于处理执行失败的场景,我们可以根据执行结果决定调用哪个函数处理。

new Promise(function(resolve, reject) { … });

Promise对象有以下几种状态:

  • pending: 初始状态;
  • resolved: 成功的操作,又称fulfilled;
  • rejected: 失败的操作。

示例如下:

  var promiseCount = 0;
  function testPromise() {
    var thisPromiseCount = ++promiseCount;

    console.log(thisPromiseCount + ') 开始(同步代码开始)');

    // 我们创建一个新的promise: 然后用'result'字符串完成这个promise (3秒后)
    var p1 = new Promise(function (resolve, reject) {
      // 完成函数带着完成(resolve)或拒绝(reject)promise的能力被执行
      console.log(thisPromiseCount + ') Promise开始(异步代码开始)');
      console.log('//等待若干秒');

      // 这只是个创建异步完成的示例
      window.setTimeout(function () {
          // 我们满足(fullfil)了这个promise!
          resolve(thisPromiseCount)
      }, Math.random() * 2000 + 1000);
    });

    // 定义当promise被满足时应做什么
    p1.then(function (val) {
      // 输出一段信息和一个值
      console.log(val + ') Promise被满足了(异步代码结束)');
    });

    console.log(thisPromiseCount + ') 建立了Promise(同步代码结束)');
  }
  testPromise();
  testPromise();
  testPromise();

输出:

1) 开始(同步代码开始)
1) Promise开始(异步代码开始)
//等待若干秒
1) 建立了Promise(同步代码结束)
2) 开始(同步代码开始)
2) Promise开始(异步代码开始)
//等待若干秒
2) 建立了Promise(同步代码结束)
3) 开始(同步代码开始)
3) Promise开始(异步代码开始)
//等待若干秒
3) 建立了Promise(同步代码结束)

Promise 对象和其原型对象定义几个非常有用的方法:

Promise.prototype.then

then() 方法接收两个函数作为参数,并分别作为 success 和 failure 状态的回调函数,then() 方法返回一个 Promise 对象。

语法:

p.then(function(succData){}, function(errData){})
p.then(function(){})

then() 的第二个参数通常省略,因为无法捕获当前then() 函数的异常,而用统一的 catch() 函数进行异常处理,下节详述

then() 使用:

then() 方法返回 Promise 对象,因此可以链式调用,而前一个 then() 函数的返回值将会被作为参数传递给下一个 then() 函数:

var p = new Promise(function(resolve, reject) {
  resolve("SUCCESS");
  //or
  //reject("FAILURE");
});

p.then(function(succData){
  console.log(succData);//success
}, function(errData){
  console.log(errData);//failure
});

链式调用:

then() 方法返回 Promise 对象,因此可以链式调用,而前一个 then() 函数的返回值将会被作为参数传递给下一个 then() 函数:

var p = new Promise(function(resolve, reject) {
  resolve(1);
});

p.then(function(val) {
  console.log(val); // 1
  return val + 1;
}).then(function(val) {
  console.log(val); // 2
}).then(function(val) {
  console.log(val); // 3
});

Promise.prototype.catch

catch() 函数处理 Promise 失败的情形,即在 Promise 中调用了 reject(data) 的情形, 也可以捕获 then() 函数中抛出的错误。

语法:

p.catch(function(errData){})

catch使用

var p = new Promise(function(resolve, reject) {
  //resolve("SUCCESS");
  //or
  reject("FAILURE");
});

p.then(function(succData){
  console.log(succData);//success
}).catch(function(errData){
  console.log(errData);//failure
});
//实际上等同于
p.then(function(succData){
  console.log(succData);//success
}.then(null, function(errData){
  console.log(errData);//failure
});

捕获 Promise 的错误

catch 也能捕获 promise语句中的错误,这种情况类似于在 promise 中调用 reject。

var p = new Promise(function(resolve, reject) {
  throw("FAILURE");
});

p.then(function(succData){
  throw new Error('FAILURE'); //不执行
}).catch(function(errData){
  console.log(errData);//FAILURE
});

捕获 then 函数的错误

var p = new Promise(function(resolve, reject) {
  resolve("SUCCESS");
});

p.then(function(succData){
  throw new Error('FAILURE');
}).catch(function(errData){
  console.log(errData);//FAILURE
});

catch 也支持链式调用

Promise 的错误总是向后抛给 catch 处理的,而 catch 的返回值也是 Promise 因此后一个 catch() 可以处理前一个 catch() 中抛出的错误

建议统一使用 catch 处理异常

尽管通过 then() 方法传递第二个参数可以处理异常,但是无法处理此个 then() 内的异常:

var p = new Promise(function(resolve, reject) {
  reject(FAILURE1);
});

p.catch(function(errData){
  console.log(errData);//FAILURE1
  throw new Error('FAILURE2');
}).catch(function(errData){
  console.log(errData);//FAILURE2
});

Promise.all

Promise.all 方法是 Promise 的一个静态方法,将多个 promise 实例(p1, p2, p3)包装成一个新的 promise 实例(p),此时会有两种执行结果:
1. p 会等所有 promise( p1, p2, p3 )都被 resolve 后 resolve,此时将这些 promise ( p1, p2, p3 )的返回值组成一个数组([p1,p2,p3]),传递给 p 的回调函数;
2. 如果 p1, p2, p3 中有一个被 reject 则该 reject ,并将该 reject的返回值传递给 p 的回调函数 。

语法:

Promise.all(iterable)

iterable 是一个可迭代对象,比如 Array,iterable 元素可以不是 promise 如果不是 promise 则会使用 Promise.resolve 转换为 Promise。

从多个数据源获取数据

下面是使用 ajax 从多个不同的接口获取数据的示例,如果所有的数据都获取成功,就可以渲染页面,否则报错。

p = Promise.race([
  fetch('/resource/data1.json'),
  fetch('/resource/data2.json'),
  fetch('/resource/data3.json'),
]).then(([d1, d2, d3]) => {
//render page
}).catch(err => {
//err handler
});

Promise.race

Promise.race 方法是 Promise 的一个静态方法,将多个 promise 实例包装成一个新的 promise 实例,和 Promise.all 不同的是,这多个 promise 实例中的任意一个 promise 被解决或拒绝后,立刻以该 promise 的状态和传递的值返回给其回调函数,方法返回一个 Promise。

语法:

Promise.race(iterable) //iterable:一个可迭代对象,比如Array。

处理 ajax 异常状态

下面是使用 ajax 获取数据的示例,第二个 promise 在5s后状态会变为 reject ,如果 fetch 在5s 内获取导数据将会正常执行,否则会触发超时错误。

p = Promise.race([
  fetch('/resource/data.json'),
  new Promise(function (resolve, reject) {
    setTimeout(() => reject(new Error('request timeout')), 5000)
  })
]).then(response => {
  //use data do sth
}).catch(error => {
  //err handler
})

Promise.resolve

Promise.resolve 方法将给定的参数转换为一个 Promise 对象,

语法:

Promise.resolve(value);
Promise.resolve(promise);
Promise.resolve(thenable);

参数是 promise 对象

参数是 promise 对象,则不做操作直接返回这个 promise 对象。

Promise.resolve(Promise.resolve('Hello, world')).then(data => console.log(data));

参数是 thenable 对象

如果参数是一个包含 then 方法的对象,resolve 方法会将这个对象转为 Promise 对象,然后执行这个对象的 then 方法。

Promise.resolve({
  then(resolve, reject) {
    resolve('Hello, world');
  }
}).then(data => console.log(data));//Hello, world

参数不是 thenable 和 promise 对象

如果参数是一个数值,或者是一个非 thenable 或非 promise 的对象,Promise.resolve 方法返回一个状态为 Resolved 的 promise 对象,并把这个参数作为返回值传递给 then 回调函数(如果存在 then 的回调)。

Promise.resolve('Hello, world').then(data => console.log(data)); //Hello, world

Promise.reject

Promise.reject 方法将给定的参数转换为一个 Promise 对象,

语法:

Promise.reject(value);
Promise.reject(promise);
Promise.reject(thenable);

具体的使用情况与 Promise.resolve 类似。

参考:

  1. Promise
  2. Promise对象
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值