1. promise 只能成功或失败一次, 而不能成功或失败两次,也不能从成功转为失败或从失败转为成功。
  2. 如果 promise 已成功或失败,且您之后添加了成功/失败回调,则将会调用正确的回调,即使事件发生在先也是如此。

Promise 对象用于表示一个异步操作的最终完成 (或失败), 及其结果值。 本质上 Promise 是一个函数返回的对象,我们可以在它上面绑定回调函数,这样我们就不需要在一开始把回调函数作为参数传入这个函数了。

概述

Promise 构造函数包含一个参数,该参数是带有 resolve(解析)和 reject(拒绝)两个参数的回调。在回调中执行一些操作(例如异步),如果一切都正常,则调用 resolve,否则调用 reject。

var promise = new Promise(function(resolve, reject) {
  // do a thing, possibly async, then…

  if (/* everything turned out fine */) {
    resolve("Stuff worked!");
  }
  else {
    reject(Error("It broke"));
  }
});

promise.then(function(result) {
  console.log(result); // "Stuff worked!"
}, function(err) {
  console.log(err); // Error:"It broke"
});

then() 包含两个参数:一个用于成功情形的回调和一个用于失败情形的回调。这两个皆可选,因此您可以只添加一个用于成功情形或失败情形的回调。

链式调用

(一)、可以在方法中返回或改变值:

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

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

(二)、还可以链接多个 then(),以便按顺序运行异步操作。当您 then() 回调中返回某些内容时:

  1. 如果返回一个值,则会以该值调用下一个 then()。
  2. 但是,如果返回类似于 Promise 对象,则下一个 then() 则会等待,并仅在 Promise 产生结果(成功/失败)时调用。
getJSON('story.json').then(function(story) {
  return getJSON(story.chapterUrls[0]);
}).then(function(chapter1) {
  console.log("Got chapter 1!", chapter1);
})

错误处理

Promise 会自动捕获内部异常,并交给 rejected 响应函数处理。then() 包含两个参数:一个用于成功,一个用于失败:

get('story.json').then(function(response) {
  console.log("Success!", response);
}, function(error) {
  console.log("Failed!", error);
})

也可以使用 catch()

get('story.json').then(function(response) {
  console.log("Success!", response);
}).catch(function(error) {
  console.log("Failed!", error);
})

错误处理的链式调用

  1. 一旦发生错误,后续所有 then() 方法的 resolve 回调 将都不会执行,直至遇到 catch()then() 方法的 reject 回调;
  2. 错误一经处理,将返回成功的 Promise,后续链式调用的 then() 会正常执行;
  3. 所以,如果在 catch() 之前的 then() 方法中通过 reject 回调处理了异常,后面的 catch() 将不会执行;
const work = new Promise((resolve) => {
    console.log('11')
    resolve('resolve-1')
    console.log('22')
}).then(data => {
    console.log(data)
    // 抛出异常
    throw new Error('Custom error message.')
}).then(res => {
    // 由于前面的异常,这个 resolve 回调不会执行
    console.log('Then after throw error')
}).then(res => {
    // 由于前面的异常,这个 resolve 回调不会执行
    console.log('Then after throw error')
    return 'resolve-22'
}, error => {
    // 截获并处理错误信息
    console.log(error.message, 'then')
}).then(res => {
    // 错误信息已被处理,该行正行打印
    console.log(res)
}).catch(error => {
    // 错误信息已被处理,当前 Promise 状态为成功,这里不会执行
    console.log(error.message, 'catch')
}).then(res => {
    // 正常输出
    console.log('after catch')
})

Promise API

  1. Promise.all(promises) —— 等待所有 promise 都 resolve 时,返回存放它们结果的数组。如果给定的任意一个 promise 为 reject,那么它就会变成 Promise.all 的 error,所有其他 promise 的结果都会被忽略。
  2. Promise.allSettled(promises)(ES2020 新增方法)—— 等待所有 promise 都 settle 时,并以包含以下内容的对象数组的形式返回它们的结果:
    • status: "fulfilled" 或 "rejected"
    • value(如果 fulfilled)或 reason(如果 rejected)。
  3. Promise.race(promises) —— 等待第一个 settle 的 promise,并将其 result/error 作为结果。
  4. Promise.resolve(value) —— 使用给定 value 创建一个 resolved 的 promise。
  5. Promise.reject(error) —— 使用给定 error 创建一个 rejected 的 promise。