await-to-js

33 阅读1分钟

本文参加了由公众号@若川视野发起的每周源码共读活动,点击了解详情一起参与

这是源码共读的第21期,链接:juejin.cn/post/708310…

源码

function to(promise, errorExt) {
  return promise
    .then(data => [null, data])
    .catch(err => {
      if (errorExt) {
        Object.assign(err, errorExt);
      }
      return [err];
    });
}

示例:

async function toTest() {
  const promise_success = new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('success');
    });
  });
  const promise_fail = new Promise((resolve, reject) => {
    setTimeout(() => {
      reject(new Error('fail'));
    });
  });
  const [err1, data1] = await to(promise_success);
  console.log(err1, data1); // null success
  const [err2, data2] = await to(promise_fail, { code: 500 });
  console.log(err2.message, err2.code, data2); // fail 500 undefined
}

toTest();

归纳

如果一个 promise 正常 resolveawait promise 返回的就是其结果。但是如果 promisereject,它将 throw 这个 error,就像在这一行有一个 throw 语句那样。

async function f() {
  await Promise.reject(new Error("出错啦!"));
}

// 等价于
async function f() {
  throw new Error("出错啦!");
}

如何处理 error

方案1:可以用 try..catch 来捕获上面提到的那个 error

async function f() {
  try {
    await Promise.reject(new Error("出错啦!"));  
  } catch (error) {
    console.log(error.message); // 出错啦!  
 }
}

如果有 error 发生,执行控制权马上就会被移交至 catch 块。

方案2:也可以在函数调用后面添加 .catch 来处理这个 error。如果我们没有 try..catch,那么由异步函数 f() 的调用生成的 promise 将变为 rejected

f().catch(e => console.log(e.message));

如果我们忘了在这添加 .catch,那么我们就会得到一个未处理的 promise error

await-to-js 就是通过方案2来处理 error