# Promise 对象

# 1.Promise 的含义

  • Promise 是异步编程的一种解决方案,避免层层嵌套的回调函数。
  • Promise 是一个对象,用它来获取异步操作的消息。Promise 提供了统一的 API,可以对异步操作的结果做进一步的处理。 Promise对象的两个特点
  • 对象的状态不受外界影响。有三种状态,pending(进行中)、fulfilled(已成功)和rejected(已失败)。
  • 一旦状态改变,就不会再变。Promise对象状态的改变只有两种可能:从pending变成fulfilled和从pending变成rejected。只要这两种情况发生了,那么状态就resolved(已定型),一直保持这个结果。 Promise对象的一些缺点
  • Promise一旦新建,就无法中途取消。
  • 如果不设置Promisecatch方法,Promise内部抛出错误,不会反应到外部。
  • 当处于pending状态时,无法得知进展到哪个阶段。
// 内部报错,外部捕获不到
try {
  new Promise((resolve, reject) => {
    console.log(w) // 此处报错
    resolve(1)
  })
} catch(e) {
  console.log('error', e)
}
// Uncaught (in promise) ReferenceError: w is not defined

// 使用catch方法就可以捕获
new Promise((resolve, reject) => {
  console.log(w) // 此处报错
  resolve(1)
}).catch(e => {

  console.log('2', e)
})
// 2 ReferenceError: w is not defined

# 2.Promise基本用法


setTimeout(_ => {
  console.log(1)
}, 0)
new Promise((resolve, reject) => {
  console.log(2) // 此处报错
  resolve(3)
  console.log(4)
}).then(value => {
  console.log(value)
})
console.log(5)

// 2 4 5 3 1
  • Promise构造函数接受一个函数作为一个参数,该函数有两个参数resolverejectresolve函数作用是将Promise对象的状态从pending变为fulfilledreject函数作用是将Promise对象的状态从pending变为rejected

return语句才会阻止后面的执行

new Promise((resolve, reject) => {
  return resolve(1)
  // 后面语句不会执行
  console.log(2)
}).then(value => {
  console.log(value)
})
// 1

# 3.Promise.prototype.then()

  • 第一个参数是resolved状态的回调函数。
  • 第二个参数是rejected状态的回调函数(可选)。
new Promise((resolve, reject) => {
  return resolve(1)
}).then(value => {
  console.log(value)
}, reason => {
  console.log(reason)
})
// 1
  • then方法返回的是一个新的Promise实例,因此可以采用链式写法。
new Promise((resolve, reject) => {
  return resolve(1)
}).then(value => {
  console.log(value)
}).then(v => {
  // 前一个then没有返回值 所以 undefined
  console.log(v)
  return 2
}).then(v => {
  // 前一个then返回2 所以输出 2
  console.log(v)
  let P2 new Promise((r, j) => {
    r(3)
  })
  return P2
}).then(v => {
  // 当前then等待的是P2状态的改变的
  console.log(v)
})
// 1 undefined 2 3

# 4.Promise.prototype.catch()

  • 运行中抛出错误,也会被catch方法捕获(throw new Error())。
const promise = new Promise(function(resolve, reject) {
  throw new Error('test');
});
promise.catch(function(error) {
  console.log(error);
});
// Error: test

var promise = new Promise(function(resolve, reject) {
  console.log(www)
});
promise.catch(function(error) {
  console.log('2', error);
});
// 2 ReferenceError: www is not defined
  • 上面的写法等价于
// 写法一
const promise = new Promise(function(resolve, reject) {
  try {
    throw new Error('test');
  } catch(e) {
    reject(e)
  }
});
// 写法二
const promise = new Promise(function(resolve, reject) {
  reject(new Error('test'));
});

# 5.Promise.prototype.finally()

  • 不管Promise对象最后状态如何,都会执行finally()方法()。
  • finally方法的回调函数不接受任何参数。
  • finally方法的实现方式。
Promise.prototype.finally = function (callback) {
  let P = this.constructor;
  return this.then(
    value  => P.resolve(callback()).then(() => value),
    reason => P.resolve(callback()).then(() => { throw reason })
  );
};

# 5.Promise.all()

  • Promise.all()方法用于将多个Promise实例,包装成一个新的Promise实例.
const p = Promise.all([p1, p2, p3]);
  • p的状态由p1p2p3决定,分成两种情况
    1. 只有p1p2p3状态都变成fulfilled,p状态就变成fulfilled,此时p1p2p3的返回值组成一个数组,传递给p的回调函数。
    2. 只要p1p2p3之中有一个状态都变成rejected,则p状态就变成rejected,此时rejected的返回值,传递给p的回调函数。

# 6.Promise.race()

  • Promise.race()方法的参数使用跟Promise.all()方法时一样的。
  • 只要p1p2p3之中有一个实例率先改变了状态,,则p的状态就跟着变。此时率先改变的实例的返回值,传递给p的回调函数。
const p = Promise.race([
  getPost(),
  new Promise(function (resolve, reject) {
    setTimeout(() => reject(new Error('request timeout')), 5000)
  })
]);

p
.then(console.log)
.catch(console.error);
  • 上面代码中,如果5秒之内getPost方法无法返回结果,变量p的状态就会变为rejected,从而触发catch方法指定的回调函数。

# 7.Promise.allSettled()

  • Promise.allSettled()方法的参数使用跟Promise.all()方法时一样的。
  • 只有p1p2p3状态都都发生了改变,此时p1p2p3的实例组成一个数组,传递给p的回调函数。
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', value: 42 },
//    { status: 'rejected', reason: -1 }
// ]

# 8.Promise.resolve()

  • 将现有的对象转为Promise对象。
  • 参数有一下四种情况
    1. 参数是一个Promise实例
      • 不做修改,直接返回当前这个实例
    2. 参数是一个thenable对象(具有then方法的对象)
      • 会立即执行then方法
    3. 参数不具有then方法,或者不是一个对象
      • 会把这个参数传给回调函数
    4. 不带参数
      • 会把这个参数(undefined)传给回调函数

# 8.Promise.resolve()

  • Promise.reject(reason)方法也会返回一个新的Promise实例,该实例的状态为rejected.
  • Promise.reject()方法的参数,会原封不动地作为reject的理由,变成后续方法的参数(这是与Promise.resolve的不同之处)。
const thenable = {
  then(resolve, reject) {
    reject('出错了');
  }
};
Promise.reject(thenable)
.catch(e => {
  console.log(e === thenable)
})
// true

# 9.Promise.any().(提案)

  • Promise.any()方法的参数使用跟Promise.all()方法时一样的。
  • 只有p1p2p3状态都变成rejected
  • 只要p1p2p3之中有一个状态变成fulfilled,则p的状态就会发生改变。
最后一次修改时间: 9/28/2020, 11:37:23 AM