Promise对象

1.promise含义

  • Promise 是异步编程的一种解决方案

  • 所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。

  • 特点:

    • 对象的状态不受外界影响

      • 有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。
      • 只有异步操作的结果, 可以决定当前是哪一种状态,任何其他操作都无法改变这个状态
    • 一旦状态改变,就不会再变,任何时候都可以得到这个结果。

      • 状态改变的两种情况:pending —》fulfilled;pending —》rejected;这两种情况发生后,状态就不会变了。再对Promise对象添加回调函数,也会立即得到这个结果。
  • 缺点

    • 一旦新建它就会立即执行,无法中途取消
    • 若不设置回调函数,Promise内部抛出的错误,不会反应到外部
    • 当处于pending状态时,无法得知目前进展到哪一个阶段

    2.基本用法

    Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject

const promise = new Promise(function(resolve, reject) {
  // ... some code
  if (/* 异步操作成功 */){
    resolve(value); //从pending变为resolved;异步操作成功时调用,将异步操作的结果,作为参数传递出去
  } else {
    reject(error);//从pending变为rejected;异步操作失败时调用,将异步操作报的错误,作为参数传递出去
  }
});

//Promise实例生成以后,用then方法分别指定resolved状态和rejected状态的回调函数。
//then接受两个回调函数作为参数,resolve时和reject时,这两个参数是可选的
promise.then(function(value) {
  // success
}, function(error) {
  // failure
});

Promise 新建后就会立即执行。

let promise = new Promise(function(resolve, reject) {
  console.log('Promise');
  resolve();
  console.log('Promise2') // 调用resolve或reject并不会终结 Promise 的参数函数的执行
});
promise.then(function() {
  console.log('resolved.');
});
console.log('Hi!');
// Promise
// Promise2
// Hi!
// resolved

一个Promise实例决定另一个Promise实例的情况

const p1 = new Promise(function (resolve, reject) {
  setTimeout(() => reject(new Error('fail')), 3000)
})
const p2 = new Promise(function (resolve, reject) {
  setTimeout(() => resolve(p1), 1000)
})
//resolve返回的是p1。由于p2返回的是另一个 Promise,导致p2自己的状态无效了,由p1的状态决定p2的状态。
p2.then(result => console.log(result))
  .catch(error => console.log(error))
// Error: fail

3.Promise.prototype.then( )

  • then方法是定义在原型对象Promise.prototype上的。它的作用是为 Promise 实例添加状态改变时的回调函数。
  • then方法的第一个参数是resolved状态的回调函数,第二个参数是rejected状态的回调函数,它们都是可选的
//getJSON是一个Promise实例
getJSON("/post/1.json").then(function(post) {
  return getJSON(post.commentURL);
}).then(function (comments) {
//then返回的是一个新的Promise实例。因此可以采用链式写法,即then方法后面再调用另一个then方法
  console.log("resolved: ", comments);
}, function (err){
  console.log("rejected: ", err);
});

4. Promise.prototype.catch( )

Promise.prototype.catch()方法是.then(null, rejection)或.then(undefined, rejection)的别名,用于指定发生错误时的回调函数

promise.then(function(data) { //cb
    // success
  }).catch(function(err) {
    // error
    //也可以捕获前面then方法执行中的错误
  });

例:

const someAsyncThing = function() {
  return new Promise(function(resolve, reject) {
    // 下面一行会报错,因为x没有声明
    resolve(x + 2);
  });
};
someAsyncThing()
.catch(function(error) {
//若someAsyncThing后不是catch,则会报错,Uncaught (in promise) ReferenceError: x is not defined
//promise中的错误会被catch捕获,会接着运行后面那个then()方法指定的回调函数。
//如果没有报错,则会跳过catch()方法
  console.log('oh no', error);
})
.then(function() {
  console.log('carry on');
});
// oh no [ReferenceError: x is not defined]
// carry on

5. Promise.prototype.finally( )

finally()方法用于指定不管 Promise 对象最后状态如何,都会执行的操作。

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

6. Promise.all()

用于将多个 Promise 实例,包装成一个新的 Promise 实例

Promise.all()方法的参数可以不是数组,但必须具有 Iterator 接口;
且返回的每个成员都是 Promise 实例,若不是,会先调用下面讲到的Promise.resolve方法,将参数转为 Promise 实例,再进一步处理
const p = Promise.all([p1, p2, p3]);

p的状态由p1、p2、p3决定,分成两种情况:

  • 只有p1、p2、p3的状态都变成fulfilled,p的状态才会变成fulfilled,此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数。
  • 只要p1、p2、p3之中有一个被rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。

如果作为参数的 Promise 实例,自己定义了catch方法,那么它一旦被rejected,并不会触发Promise.all()的catch方法
p2没有自己的catch方法,就会调用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: 报错了]

7.Promise.race( )

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

只要p1、p2、p3之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p的回调函数。
const p = Promise.race([p1, p2, p3]);

8.Promise.allSettled( )

Promise.allSettled()方法接受一个数组作为参数,数组的每个成员都是一个 Promise 对象,并返回一个新的 Promise 对象。只有等到参数数组的所有 Promise 对象都发生状态变更(不管是fulfilled还是rejected),返回的 Promise 对象才会发生状态变更。

const resolved = Promise.resolve(42);
const rejected = Promise.reject(-1);
const allSettledPromise = Promise.allSettled([resolved, rejected]);
allSettledPromise.then(function (results) {
  console.log(results);
});
// 成员对象的status属性的值只可能是字符串fulfilled或字符串rejected
// [
//    { status: 'fulfilled', value: 42 },
//    { status: 'rejected', reason: -1 }
// ]

9. Promise.any( )

只要参数实例有一个变成fulfilled状态,包装实例就会变成fulfilled状态;如果所有参数实例都变成rejected状态,包装实例就会变成rejected状态。

10.Promise.resolve( )

将现有对象转为 Promise 对象

Promise.resolve('foo')
// 等价于
new Promise(resolve => resolve('foo'))

11.Promise.reject( )

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

const p = Promise.reject('出错了');
// 等同于
const p = new Promise((resolve, reject) => reject('出错了'))
p.then(null, function (s) {
  console.log(s)
});
// 出错了

出自:阮一峰–ECMAScript 6 入门

你可能感兴趣的:(Js,javascript,前端,vue.js)