Skip to content

promise 用于处理一个不能立即确定返回状态的操作(异步)的错误结果

js
let promise = new Promise(function(resolve, reject) {
  // executor 异步操作
});

任务成功则调用 resolve 回调,否则调用 reject 回调。

基本

生产者 (异步操作)

promise 对象内部属性

  • state —— 最初是 "pending",然后在 resolve 被调用时变为 "fulfilled"(满足的),或者在 reject 被调用时变为 "rejected"
  • result —— 最初是 undefined,然后在 resolve(value) 被调用时变为 value,或者在 reject(error) 被调用时变为 error确定状态:
js
let promise = new Promise(function(resolve, reject) {
  // 当 promise 被构造完成时,自动执行此函数

  // 1 秒后发出工作已经被完成的信号,并带有结果 "done"
  setTimeout(() => resolve("done"), 1000);
});

错误状态:

js
let promise = new Promise(function(resolve, reject) {
  // 1 秒后发出工作已经被完成的信号,并带有 error
  setTimeout(() => reject(new Error("Whoops!")), 1000);
});

状态只允许改变一次,后续更改均无效。

消费者 (依赖异步状态的操作)

then 接受两个参数,第一个为状态接收为 resolved 时执行的后续操作,第二个为 rejected 时的操作。

js
promise.then(
  result => alert(result), // 1 秒后显示 "done!"
  error => alert(error) // 不运行
);

catch 等价于 then(null,error =>{ })

js
promise.catch(alert);

finally 当 promise 状态确定后执行。 设置一个处理程序在前面的操作完成后,执行清理/终结。 不应该返回任何内容。

  • finally 处理程序没有得到前一个处理程序的结果(它没有参数)。而这个结果被传递给了下一个合适的处理程序。
  • 如果 finally 处理程序返回了一些内容,那么这些内容会被忽略。
  • 当 finally 抛出 error 时,执行将转到最近的 error 的处理程序(catch 方法)。

总结

  1. 处理程序只要 promise 的 state 被决定就可以立即被执行。
  2. 例子:基于 promise 的延时
js
function delay(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

delay(3000).then(() => alert('runs after 3 seconds'));

调用 delay 函数,将在 ms 后决定 promise 对象的状态,当状态敲定后执行 then,即弹出通知。

Promise 链式调用

每个对 .then 的调用都会返回了一个新的 promise。

js
new Promise(function(resolve, reject) {

  setTimeout(() => resolve(1), 1000); // (*)

}).then(function(result) { // (**)

  alert(result); // 1
  return result * 2;

}).then(function(result) { // (***)

  alert(result); // 2
  return result * 2;

}).then(function(result) {

  alert(result); // 4
  return result * 2;

});

与分开的三次 then 不同,这里的*2 是将 promise 的参数多次改变结果参数,因为每次返回的是结果参数变更后的 promise。