【面试】‘return await promise‘ 与 ‘return promise‘ 这细微的区别,你的可能还不知道?

简介: 当从一个异步函数的promise返回时,我们可以使用return await promise等待 promise 解析完,也可以直接返回它 return promise。

当从一个异步函数的promise返回时,我们可以使用return await promise等待 promise 解析完,也可以直接返回它 return promise。


async function func1() {
  const promise = asyncOperation();
  return await promise;
}
// vs
async function func2() {
  const promise = asyncOperation();
  return promise;
}

这两个表达式都是有效的。然而,在某些情况下,这些表达式的表现会有所不同吗?我们往下看。


1. 相同的行为


为了找到这两个表达式(返回 await promise vs return promise)之间的区别,我们需要一个辅助函数 delayedDivide(n1, n2)。


该函数除2个数字,并返回包含在promise中的除法结果:


function promisedDivision(n1, n2) {
  if (n2 === 0) {
    return Promise.reject(new Error('Cannot divide by 0'));
  } else {
    return Promise.resolve(n1 / n2);
  }
}

如果第二个参数(除数)是 0,该函数返回一个 reject,因为除以 0 是不可能的。


定义了辅助函数之后,我们来跑几个例子。


下面的函数divideWithAwait()使用return await promisedDivision(6,2)表达式来返回包裹在promise中的 6 除以 2 的除法


async function divideWithAwait() {
  return await promisedDivision(6, 2);
}
async function run() {
  const result = await divideWithAwait();
  console.log(result); // logs 3
}
run();

事例地址:https://codesandbox.io/s/with-await-resolved-mdzz5?file=/src/index.js


在run()函数中,await divideWithAwait()表达式的计算结果为除法结果 3,一切正常。


如果有返回不带await关键字,结果又会怎么样呢?


async function divideWithoutAwait() {
  return promisedDivision(6, 2);
}
async function run() {
  const result = await divideWithoutAwait();
  console.log(result); // logs 3
}
run();

事例地址:https://codesandbox.io/s/without-await-resolved-u06sb


即使在divideWithoutAwait() 中没有使用 await 关键字,run() 函数中的表达式awaitdivideWithoutAwait() 的结果也是正确的。


在这一步,我们已经看到使用return await promise和return promise并没有什么不同。


2.不同行为


现在我们采用另一种方法,要使函数 promisedDivision(n1, n2)返回一个被拒绝的promise,我们将第二个参数设置为 0。


因为promisedDivis


async function divideWithAwait() {
  try {
    return await promisedDivision(5, 0);
  } catch (error) {
    // Rejection caught
    console.log(error); // logs Error('Cannot divide by 0')
  }
}
async function run() {
  const result = await divideWithAwait();
}
run();
ion(n1, 0) 会返回一个异常


事例地址:https://codesandbox.io/s/with-await-rejected-ihxg5?file=/src/index.js


如果没有 await,结果又会怎么样?


,我们使用 try {... } catch (error) {...}。


async function divideWithoutAwait() {
  try {
    return promisedDivision(5, 0);
  } catch (error) {
    // Rejection NOT caught
    console.log(error);
  }
}
async function run() {
  const result = await divideWithoutAwait();
}
run(); // Uncaught Error: Cannot divide by 0

事例地址:https://codesandbox.io/s/without-await-rejected-477nr?file=/src/index.js


然而,这次,catch(error) { ... }并没有捕捉到异常。


到这,我们就使用return await promise和return promise之间的主要区别了。

相关文章
阿里面试:PS+PO、CMS、G1、ZGC区别在哪?什么是卡表、记忆集、联合表?问懵了,尼恩来一个 图解+秒懂+史上最全的答案
阿里面试:PS+PO、CMS、G1、ZGC区别在哪?什么是卡表、记忆集、联合表?问懵了,尼恩来一个 图解+秒懂+史上最全的答案
使用 async/await 结合 try/catch 处理 Promise.reject()抛出的错误时,有什么需要注意的地方?
使用 async/await 结合 try/catch 处理 Promise.reject()抛出的错误时,有什么需要注意的地方?
141 57
Promise.reject()和throw有什么区别?
Promise.reject()和throw有什么区别?
130 57
Promise.allSettled() 和 Promise.all() 有什么区别?
Promise.allSettled() 和 Promise.all() 有什么区别?
143 74
Java 高级面试技巧:yield() 与 sleep() 方法的使用场景和区别
本文详细解析了 Java 中 `Thread` 类的 `yield()` 和 `sleep()` 方法,解释了它们的作用、区别及为什么是静态方法。`yield()` 让当前线程释放 CPU 时间片,给其他同等优先级线程运行机会,但不保证暂停;`sleep()` 则让线程进入休眠状态,指定时间后继续执行。两者都是静态方法,因为它们影响线程调度机制而非单一线程行为。这些知识点在面试中常被提及,掌握它们有助于更好地应对多线程编程问题。
155 9
Java面试必问!run() 和 start() 方法到底有啥区别?
在多线程编程中,run和 start方法常常让开发者感到困惑。为什么调用 start 才能启动线程,而直接调用 run只是普通方法调用?这篇文章将通过一个简单的例子,详细解析这两者的区别,帮助你在面试中脱颖而出,理解多线程背后的机制和原理。
121 12
Android经典面试题之Kotlin中Lambda表达式和匿名函数的区别
Lambda表达式和匿名函数都是Kotlin中强大的特性,帮助开发者编写简洁而高效的代码。理解它们的区别和适用场景,有助于选择最合适的方式来解决问题。希望本文的详细讲解和示例能够帮助你在Kotlin开发中更好地运用这些特性。
63 9
Promise.allSettled()方法和Promise.race()方法有什么区别?
`Promise.allSettled()` 提供了一种更全面、更详细的方式来处理多个 `Promise`,而 `Promise.race()` 则更强调速度和竞争。我们需要根据具体的需求来选择使用哪种方法。
面试官刁钻提问?轻松应对 break、continue 和 return 的巧妙用法
小米,一位技术博主,针对 Java 面试中常见的 `break`、`continue` 和 `return` 关键字进行了详细讲解。通过打怪故事和代码实例,解释了它们的使用场景及注意事项,帮助读者更好地理解和应用这些控制语句。
62 12
面试官刁钻提问?轻松应对 break、continue 和 return 的巧妙用法

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等