Promise 构造函数接收一个参数,一个 executor
函数,JavaScript 然后执行你的 executor
具有 2 个参数的函数: resolve()
和 reject()
。
function executor(resolve, reject) {
typeof resolve; // function
typeof reject; // function
}
new Promise(executor);
你的 executor 函数负责调用 resolve()
将 Promise 标记为已 完成 (成功)或被 拒绝 (失败)。
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
您可以使用 then()
功能 。
const success = new Promise(function executor(resolve) {
setTimeout(() => resolve(OK), 100);
});
const start = Date.now();
return success.then(function onFulfilled(str) {
str; // OK
const elapsed = Date.now() - start;
elapsed; // Approximately 100
});
使用 Promise 进行超时
你不需要经常创建新的 Promise。 通常像 Axios 或 Mongoose 内部创建 Promise 并返回它们,因此您可以使用 then()
或者 await
,但是并非所有 API 都支持 Promise。 例如 , setTimeout()
函数 只接受回调。
为了创建一个在解析前等待 100 毫秒的 Promise,你应该包装一个 setTimeout()
给 new Promise
:
async function test() {
// Pause the async function for 100ms
await new Promise(resolve => setTimeout(resolve, 100));
return OK;
}
const start = Date.now();
await test();
const elapsed = Date.now() - start;
elapsed; // Approximately 100
Wrapping Node-Style Callbacks
一些异步 Node.js API,例如 fs.readFile()
,不返回 Promise。你还需要包装 fs.readFile()
在一个 new Promise
为了将它与 async/await 一起使用。
确保您处理错误! 节点风格的回调 有 2 个参数:一个 error
和一个 result
,如果 error
不是 无效 的,你应该拒绝承诺。
const fs = require(fs);
const p = new Promise(function executor(resolve, reject) {
fs.readFile(./package.json, (error, result) => {
if (error != null) {
// Note the early return!
return reject(error);
}
resolve(result);
});
});
const pkg = JSON.parse(await p);
pkg.name; // masteringjs.io
异步执行器函数
一个常见的错误是使执行程序成为 异步函数 。
const p = new Promise(async function executor(resolve, reject) {
await new Promise(resolve => setTimeout(resolve, 100));
resolve(OK);
});
const str = await p;
上面的代码工作正常,但它创建了一个不必要的承诺(请记住,异步函数总是返回一个承诺!)并且看起来很笨拙。 由于异步函数总是返回承诺,你总是可以用普通的异步函数调用替换异步执行器函数:
async function test() {
await new Promise(resolve => setTimeout(resolve, 100));
return OK;
}
const p = test();
关键的一点是你永远不应该让执行器函数异步。
请登录后查看评论内容