理解 JavaScript 中的 new Promise

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();

关键的一点是你永远不应该让执行器函数异步。

© 版权声明
THE END
喜欢就支持一下吧
点赞836 分享
评论 抢沙发

请登录后发表评论

    请登录后查看评论内容