javascript - JS : async function implicitly unwraps promise?

标签 javascript node.js asynchronous promise async-await

据我所知,异步函数将它们的返回值隐式包装到一个 promise 中。这确实适用于每个属性,除了 Promises 本身。

async function f() {
  return new Promise((res) => {
    setTimeout(() => {
      res("Why am I being unwrapped")
    }, 1000)
  })
}

(async () => {
  console.log(await f())
})()

那些在返回之前会被打开。所以 await f() 实际上等待两个嵌套的 promise。

Note that this also works with explicitly createded Promises (Promise.resolve(new Promise(...)))

是否有好的方法来避免这种情况?我真的很想有一个没有像这样的 quickfix 的嵌套 Promise。

async function y() {
  return {wrapped: new Promise((res) => {
    setTimeout(() => {
      res("Why am I being unwrapped")
    }, 1000)
  })}
}

(async () => {
  console.log((await y()).wrapped)
})()

Sandbox

最佳答案

根据 MDN documentation on async functions :

Async functions always return a promise. If the return value of an async function is not explicitly a promise, it will be implicitly wrapped in a promise.

换句话说,由于您要返回一个 Promise,因此它不会被包装。如果你想重新包装它,你可以,但你也可以去除具有类似效果的 async 关键字。 除非await它,否则您会得到原始的 Promise。

如此有效:

function f() {
  return new Promise((res) => {
    setTimeout(() => {
      res("Might be wrappers on some of you, but not on me!")
    }, 1000)
  })
}

(async () => {
  console.log(f())
})()

它给你这样的输出:

Promise { <pending> }

如果目标是拥有一个返回原始 Promise 的 Promise,那么您将与 Promise 系统设计的所有功能作斗争,即在发现 Promise 时自动解包。 Promise.resolve() 包装所有 Promise,如果您以某种方式给它一个 Promise,它会递归地解包。

你可以通过返回一些不是 Promise 的东西来做到这一点,就像你的例子一样,但这似乎违背了 Promises 的全部目的。

如果你有一个特定的问题,你试图解决它绝对需要一个延迟的 promise ,考虑返回一个函数而不是一些任意对象:

function f() {
  return () => {
    return new Promise((res) => {
      setTimeout(() => {
        res("I'll start as soon as you ask.")
      }, 1000)
    })
  };
}

然后您可以调用 let p = f() ,然后在您想要获得实际 Promise 时调用 p()。这就是 JavaScript 通常处理延迟执行的方式。

如果您想立即启动对 Promise 的执行,您仍然可以适应:

function f() {
  const p = new Promise((res) => {
    setTimeout(() => {
      res("Already underway when requested.")
    }, 1000)
  })

  return () => { p };
}

尽管通常最好尽可能避免使用这些技术,而且通常是这样。

关于javascript - JS : async function implicitly unwraps promise?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61762358/

相关文章:

node.js - 在单独的模块中定义 Mongoose 模型

node.js - 如何处理 'promis'的数组

javascript - 在 node.js 应用程序中使用 $or 运算符的命令行参数有什么问题?

javascript - 替换重复的字符不起作用

node.js - 如何在 Electron-vue 应用程序中为 fs.readdir(path) 指定另一个磁盘?

java - 等待 CompletableFuture 列表

java - 在 Controller 中使用 @Async 和 CompletableFuture 可以提高我们 api 的性能吗?

javascript - 如何使用嵌套请求处理异步 token 更新?

javascript - 重复函数执行 n 秒

javascript - Meteor Tracker 无法自动接收订阅