异步函数使用 Promise 解析但 returns 未定义

async function resolve with Promise but returns undefined

我正在使用 await 从数据库中读取数据,所以我使用了 Promise,但该函数似乎 return 没有任何作用

async function read() {
  return new Promise((resolve, reject) => {
    const db = new DB();
  
    db
    .read()
    .then(result => {
      resolve(result);
    }).catch(() => {
      reject('db-error');
    });
  });
}

(async () => {
  const data = await read();

  console.log(data); // undefined
})();

如何使 read() return 结果?

你让它变得比它必须的更复杂。如果您已经在使用 API 和 returns promise,则无需自己使用 promise 构造函数。

并且仅当您在其中使用 await 来处理承诺时才需要将函数声明为 async

所以要么:

function read() {
  const db = new DB();
  return db
    .read()
    .catch(() => {
      return 'db-error';
    });
}

或者

async function read() {
  const db = new DB();
  try {
    return await db.read();
  } catch(error) {
    return 'db-error';
  }
}

如果你仍然没有得到你想要的值,那么你没有正确使用数据库 API,你必须阅读它的文档来弄清楚如何取回正确的数据。

写 MDN Web 文档的那些很棒的人说,如果正在等待的承诺被拒绝,await 的结果将是 undefinedhttps://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await#handling_rejected_promises

查看以下场景。

这是一个简单的函数,returns 一个 Promise:

function asyncFunc(waitTime) {
  return new Promise((resolve, reject) => {
   setTimeout(() => {
     // say we prefer people who do things in 3 seconds or less
     if (waitTime <= 3000) {
       resolve('Promise resolved! You\'re fast! :)');
     } else {
       reject('Promise rejected! You\'re slow! :(');
     }
   }, waitTime);
 });

}

让我们使用与您类似的方法测试该功能:

async function testAsyncFunc(waitTime) {
  try {
    const result = await asyncFunc(waitTime);
    console.log(result);
  } catch(error) {
      console.error(error.message);
  }
}

testAsyncFunc(3000); // Returns `Promise resolved! You're fast! :)`, as expected

testAsyncFunc(3001); // Returns `undefined` instead of `Promise rejected! You're slow! :(` 

但是由于我们想要异步操作的实际拒绝错误而不是 undefined,解决方案是将 catch 链接到 await 语句以在您调用异步函数时立即捕获任何拒绝错误然后抛出错误,以便它可以被您可能想要使用的任何 catch 错误处理程序捕获,如下所示:

async function testAsyncFunc(waitTime) {
  try {
    const result = await asyncFunc(waitTime)
      .catch(error => {
        // throw the rejection error so it can be handled by the catch block below
        throw new Error(error);
      });
    // if no errors
    console.log(result);
  } catch(error) {
      console.error(error.message);
  }
}

testAsyncFunc(3001); // Returns the expected result: `Promise rejected! You're slow! :(`