跳至主要內容

Promise

大约 2 分钟featurees-standard

Promise

模块

类型

class Promise<T> {
  constructor(
    executor: (
      resolve: (value: T) => void,
      reject: (reason: any) => void
    ) => void
  );
  then(onFulfilled: Function, onRejected: Function): Promise<T>;
  catch(onRejected: Function): Promise<T>;
  finally(onFinally: Function): Promise<T>;
  static resolve<U>(x: U): Promise<U>;
  static reject<U>(r: U): Promise<U>;
  static all<U>(iterable: Iterable<Promise<U>>): Promise<Array<U>>;
  static allSettled<U>(iterable: Iterable<Promise<U>>): Promise<Array<U>>;
  static any<U>(promises: Iterable<U>): Promise<U>;
  static race<U>(iterable: Iterable<U>): Promise<U>;
}

入口点

core-js(-pure)/es|stable|actual|full/promise
core-js(-pure)/es|stable|actual|full/promise/all-settled
core-js(-pure)/es|stable|actual|full/promise/any
core-js(-pure)/es|stable|actual|full/promise/finally

示例

基础示例open in new window:

function sleepRandom(time) {
  return new Promise((resolve, reject) => {
    setTimeout(resolve, time * 1e3, 0 | (Math.random() * 1e3));
  });
}

console.log("Run"); // => Run
sleepRandom(5)
  .then((result) => {
    console.log(result); // => 869,5秒后输出。
    return sleepRandom(10);
  })
  .then((result) => {
    console.log(result); // => 202,10秒后输出。
  })
  .then(() => {
    console.log("immediately after"); // => immediately after
    throw Error("Irror!");
  })
  .then(() => {
    console.log("will not be displayed");
  })
  .catch((x) => console.log(x)); // => => Error: Irror!

Promise.resolvePromise.reject 示例open in new window:

Promise.resolve(42).then((x) => console.log(x)); // => 42
Promise.reject(42).catch((x) => console.log(x)); // => 42

Promise.resolve($.getJSON("/data.json")); // => ES promise

Promise#finally 示例open in new window:

Promise.resolve(42).finally(() => console.log("You will see it anyway"));

Promise.reject(42).finally(() => console.log("You will see it anyway"));

Promise.all 示例open in new window:

Promise.all([
  "foo",
  sleepRandom(5),
  sleepRandom(15),
  sleepRandom(10), // 15秒后:
]).then((x) => console.log(x)); // => ['foo', 956, 85, 382]

Promise.race exampleopen in new window:

function timeLimit(promise, time) {
  return Promise.race([
    promise,
    new Promise((resolve, reject) => {
      setTimeout(reject, time * 1e3, Error("Await > " + time + " sec"));
    }),
  ]);
}

timeLimit(sleepRandom(5), 10).then((x) => console.log(x)); // => 853,5秒后。
timeLimit(sleepRandom(15), 10).catch((x) => console.log(x)); // Error: Await > 10 sec

Promise.allSettled 示例open in new window:

Promise.allSettled([
  Promise.resolve(1),
  Promise.reject(2),
  Promise.resolve(3),
]).then(console.log); // => [{ value: 1, status: 'fulfilled' }, { reason: 2, status: 'rejected' }, { value: 3, status: 'fulfilled' }]

Promise.any 示例open in new window:

Promise.any([Promise.resolve(1), Promise.reject(2), Promise.resolve(3)]).then(
  console.log
); // => 1

Promise.any([Promise.reject(1), Promise.reject(2), Promise.reject(3)]).catch(
  ({ errors }) => console.log(errors)
); // => [1, 2, 3]

异步函数示例open in new window

let delay = (time) => new Promise((resolve) => setTimeout(resolve, time));

async function sleepRandom(time) {
  await delay(time * 1e3);
  return 0 | (Math.random() * 1e3);
}

async function sleepError(time, msg) {
  await delay(time * 1e3);
  throw Error(msg);
}

(async () => {
  try {
    console.log("Run"); // => Run
    console.log(await sleepRandom(5)); // => 936,5秒后。
    let [a, b, c] = await Promise.all([
      sleepRandom(5),
      sleepRandom(15),
      sleepRandom(10),
    ]);
    console.log(a, b, c); // => 210 445 71,15秒后。
    console.log("Will not be displayed");
  } catch (e) {
    console.log(e); // => Error: 'Error!',5秒后。
  }
})();

未处理的拒绝跟踪

在 Node.js 中,像原生实现一样,可用的事件 unhandledRejectionopen in new windowrejectionHandledopen in new window

process.on("unhandledRejection", (reason, promise) =>
  console.log("unhandled", reason, promise)
);
process.on("rejectionHandled", (promise) => console.log("handled", promise));

let promise = Promise.reject(42);
// unhandled 42 [object Promise]

setTimeout(() => promise.catch(() => {}), 1e3);
// handled [object Promise]

在浏览器中被拒绝时,默认情况下你会在控制台中看到提示,或者可以设置一个自定义的 handler 和一个用于未处理时间的 handler,示例open in new window:

window.addEventListener("unhandledrejection", (e) =>
  console.log("unhandled", e.reason, e.promise)
);
window.addEventListener("rejectionhandled", (e) =>
  console.log("handled", e.reason, e.promise)
);
// 或者
window.onunhandledrejection = (e) =>
  console.log("unhandled", e.reason, e.promise);
window.onrejectionhandled = (e) => console.log("handled", e.reason, e.promise);

let promise = Promise.reject(42);
// => unhandled 42 [object Promise]

setTimeout(() => promise.catch(() => {}), 1e3);
// => handled 42 [object Promise]