一般来说,有 4 种方法可以在 JavaScript 中创建新的 Promise:

使用 Promise 构造函数

接受 Promise 构造函数 一个参数,一个 executor 功能。你调用 new Promise(executor) 时,JavaScript 立即执行你的 executor 具有 2 个参数的函数: resolve()reject()

function executor(resolve, reject) {
  typeof resolve; // function
  typeof reject; // function
}

new Promise(executor);

executor() 然后函数负责调用 resolve() 将承诺标记为已 完成 (成功)或被 拒绝 (失败)。

const success = new Promise(function executor(resolve) {
  resolve(OK);
});

const fail = new Promise(function executor(resolve, reject) {
  reject(new Error(Oops));
});

const str = await success;
str; // OK

const err = await fail.catch(err => err);
err.message; // Oops

使用静态助手

Promise.resolve() 函数允许您创建一个立即履行的新承诺。

const p = Promise.resolve(42);
p.then(v => {
  v; // 42
});

你可以想到 Promise.resolve(v) 简称 new Promise(resolve => resolve(v)),同样 Promise.reject() 函数允许您创建一个立即被拒绝的新承诺。

const p = Promise.reject(new Error(Oops!));
p.catch(err => {
  err.message; // Oops!
});

小心 Promise.reject():如果您不立即添加 .catch() 处理你的新承诺,你会得到一个 未处理的承诺拒绝

then()catch()

你调用 .then() 或者 .catch(),JavaScript 创建一个新的 Promise。

const p = Promise.resolve(Hello);

const p2 = p.then(str => `${str} World`);

p2 instanceof Promise; // true
p2 === p; // false

异步函数

当你调用一个异步函数时,JavaScript 会返回一个新的 Promise。 不管你是什么 return 从异步函数中,JavaScript 总是返回一个 Promise,所以确保你 await 上异步函数调用。

async function test() {
  return 42;
}

test() instanceof Promise; // true

不执行

JavaScript Promise 是 hot ,因为 JavaScript 会立即执行 executor 函数。

如果你发现自己想要一个 冷漠 的承诺,因为你的承诺直到你 await 在它上面,你应该只使用一个异步函数。 每次调用异步函数都会返回一个新的 Promise。

async function getAnswer() {
  return 42;
}

const p1 = getAnswer();
p1 instanceof Promise; // true

const p2 = getAnswer();
p2 instanceof Promise; // true
p2 === p1; // false

另一种常见的替代方案是 延迟模式 ,您可以在其中创建具有 resolve()reject() 可以在外部调用的函数 executor() 功能。

Promise.deferred = function() {
  let resolve = null;
  let reject = null;
  const p = new Promise((_resolve, _reject) => {
    resolve = _resolve;
    reject = _reject;
  });
  return Object.assign(p, { resolve, reject });
};

const p = Promise.deferred();

p.then(v => {
  v; // 42
});

p.resolve(42);

但是, 延迟模式被认为是一种反模式 。 那是因为发生在 executor 函数之外的同步错误不会拒绝 promise。

// JavaScript catches any errors that occur in the promise executor
// and treats them as a promise rejection.
const p1 = new Promise(() => { throw new Error(Oops!); });
p1.catch(err => {
  err.message; // Oops!
});

// With `deferred`, youre responsible for handling errors that
// occur outside the executor. If you forget, your promise will
// be pending forever like `p2` below.
const p2 = Promise.deferred();
throw new Error(Oops!);
© 版权声明
评论 抢沙发

请登录后发表评论