一般来说,有 4 种方法可以在 JavaScript 中创建新的 Promise:
- 使用 _
Promise
构造函数 - 使用静态助手
Promise.resolve()
和Promise.reject()
then()
功能 或catch()
功能- 调用 异步函数
使用 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!);
请登录后查看评论内容