ES6 promise对象部分分析

前几天一个朋友问:promise知道吗?

我也是集合了一下当前比较好的文章和案例给大家总结一下,下面开始。

Promise 是异步编程的一种解决方案,它由社区最早提出和实现,然后由ES6 将其写进了语言标准,统一了用法,原生提供了Promise 对象。

所谓Promise ,类似一个容器(假设一个大箱子,里面有很多你想的要的东西,只要你想的,哪里都有)。我理解的Promise就是一个对象,使用它主要可以获取异步操作的消息。在Promise对象上提供了一些 API,对各种异步操作都可进行处理。

Promise 对象特点:

(1)对象的状态不受外界影响。Promise 对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled/resolve(已成功)和rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。

(2)一旦状态发生改变,就不会再改变,无论任何时候都可以得到这个结果。Promise对象状态的改变,有两种情况:从pending变为fulfilled和从pending变为rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果,这时就称为 resolved(已定型)。

Promise 对象缺点:

第一,无法取消Promise一旦新建它就会立即执行,无法中途取消。第二,如果不设置回调函数,Promise内部抛出的错误,不会反应到外部。第三,当处于pending状态时,无法得知目前进展到哪一个阶段(刚开始pending过程还是即将结束pending的过程)。

基本用法:创建Promise对象

const promise = new Promise(function(resolve, reject) {
  if (/* 成功响应异步操作完成 */){
    resolve(success);
  } else {
    reject(error);
  }
});
Promise构造函数接受一个函数作为参数,然后该函数所需要的两个参数分别是resolve和reject。
这两个参数由 JavaScript 引擎提供,不用自己部署。

resolve函数的作用是,将Promise对象的状态从“未完成”变为“成功”(即从 pending 变为 resolved),
在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;将success传递出去。
reject函数的作用是,将Promise对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected),
在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去;将error传递出去。

基本用法:创建Promise对象后.then方法回调处理

promise.then(function(value) {
  // success
}, function(error) {
  // error
});

then方法可以接受两个回调函数作为参数。
第一个回调函数是Promise对象的状态变为resolved时调用。
第二个回调函数是Promise对象的状态变为rejected时调用。
其中,第二个函数是可选的,不一定要提供。这两个函数都接受Promise对象传出的值作为参数。

看下面例子,体会执行顺序

let promise = new Promise(function(resolve, reject) {
  console.log('Promise');
  resolve();
});

promise.then(function() {
  console.log('resolved');
});

console.log('Hi');

// Promise
// Hi
// resolved

下面是一个使用Promise对象实现的 Ajax-get 例子

const getJSON = function(url) {
  const promise = new Promise(function(resolve, reject){
    const client = new XMLHttpRequest();
    client.open("GET", url);
    client.onreadystatechange = handler;
    client.responseType = "json";
    client.setRequestHeader("Accept", "application/json");
    const handler = function() {
      if (this.status === 200&&this.readyState == 4) {
        resolve(this.response);
      } else {
        reject(new Error(this.statusText));
      }
    };
    client.send();
  });
  return promise;
};

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

其实吧...你也可以自己封装一个promise-post请求...这里先不说了,有时间补上...

Promise.prototype.then()   个人觉得then 这知识点还好

Promise.prototype.catch()  个人比较烦catch这块,花点时间还得在搞一下

Promise.prototype.finally()  方法用于指定不管 Promise 对象最后状态如何,都会执行的操作。不管Promise最后的状态,在执行完thencatch指定的回调函数以后,都会执行finally方法指定的回调函数。finally方法的回调函数不接受任何参数,这意味着没有办法知道,前面的 Promise 状态到底是fulfilled还是rejected。这表明,finally方法里面的操作,应该是与状态无关的,不依赖于 Promise 的执行结果。

promise
.then(result => {···})
.catch(error => {···})
.finally(() => {···});

Promise.all()  方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。Promise.all方法接受一个数组作为参数,且都是 Promise 实例。(Promise.all方法的参数可以不是数组,但必须具有 Iterator 接口,且返回的每个成员都是 Promise 实例。)

// 生成一个Promise数组
const promises = [2, 3, 5, 7, 11, 13].map(function (i) {
  return getJSON('/post/' + i + ".json");
});

Promise.all(promises).then(function (value) {
  // ...
}).catch(function(error){
  // ...
});

上面代码中,promises是包含 6 个 Promise 实例的数组,只有这 6 个实例的状态都变成fulfilled,或者其中有一个变为rejected,才会调用Promise.all方法后面的回调函数。

const a = aa();

const b = bb
  .then(b);

const c = cc
  .then(c);

Promise.all([
  b,
  c
])
.then(([bbb, ccc]) => pick(bbb,ccc));

上面代码中,b和c是两个异步操作,只有等到它们的结果都返回了,才会触发pick这个回调函数。

注意,如果作为参数的 Promise 实例,自己定义了catch方法,那么它一旦被rejected,并不会触发Promise.all()的catch方法。
(这里我们没有定义)

看下面的例子

const p1 = new Promise((resolve, reject) => {
  resolve('hello');
})
.then(result => result)
.catch(e => e);

const p2 = new Promise((resolve, reject) => {
  throw new Error('报错了');
})
.then(result => result)
.catch(e => e);

Promise.all([p1, p2])
.then(result => console.log(result))
.catch(e => console.log(e));
// ["hello", Error: 报错了]

上面代码中,p1会resolved,p2首先会rejected,但是p2有自己的catch方法,
该方法返回的是一个新的 Promise 实例,p2指向的实际上是这个实例。
该实例执行完catch方法后,也会变成resolved,导致Promise.all()
方法参数里面的两个实例都会resolved,因此会调用then方法指定的回调函数,
而不会调用catch方法指定的回调函数。

如果p2没有自己的catch方法,就会调用Promise.all()的catch方法。

const p1 = new Promise((resolve, reject) => {
  resolve('hello');
})
.then(result => result);

const p2 = new Promise((resolve, reject) => {
  throw new Error('报错了');
})
.then(result => result);

Promise.all([p1, p2])
.then(result => console.log(result))
.catch(e => console.log(e));
// Error: 报错了

Promise.race() Promise.race方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例。

Promise.resolve() 有时需要将现有对象转为 Promise 对象,Promise.resolve方法就起到这个作用。

Promise.reject() Promise.reject(reason)方法也会返回一个新的 Promise 实例,该实例的状态为rejected

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值