Javascript JS:异步函数隐式展开承诺?

Javascript JS:异步函数隐式展开承诺?,javascript,node.js,asynchronous,promise,async-await,Javascript,Node.js,Asynchronous,Promise,Async Await,据我所知,异步函数隐式地将其返回值包装成承诺。这对每一个财产都有效,除了他们自己 异步函数f(){ 返回新承诺((res)=>{ 设置超时(()=>{ res(“我为什么被打开包装”) }, 1000) }) } (异步()=>{ log(等待f()) })() 这些东西在被退回之前会被拆开。因此,await f()实际上在等待两个嵌套的承诺 请注意,这也适用于显式创建的承诺(Promise.resolve(新承诺(…))) 有什么好的方法可以避免这种情况吗?我真的希望有一个嵌套的承诺,而不是

据我所知,异步函数隐式地将其返回值包装成承诺。这对每一个财产都有效,除了他们自己

异步函数f(){ 返回新承诺((res)=>{ 设置超时(()=>{ res(“我为什么被打开包装”) }, 1000) }) } (异步()=>{ log(等待f()) })() 这些东西在被退回之前会被拆开。因此,
await f()
实际上在等待两个嵌套的承诺

请注意,这也适用于显式创建的承诺(
Promise.resolve(新承诺(…))


有什么好的方法可以避免这种情况吗?我真的希望有一个嵌套的承诺,而不是像这样的快速修复

异步函数y(){ 返回{wrapped:newpromise((res)=>{ 设置超时(()=>{ res(“我为什么被打开包装”) }, 1000) })} } (异步()=>{ console.log((wait y()).wrapped) })()

根据:

异步函数总是返回一个承诺。如果异步函数的返回值不是显式的承诺,它将隐式地包装在承诺中

换言之,既然你在回报一个承诺,它就不会被包装起来。如果你想重新包装它,你可以,但是你也可以去掉具有类似效果的
async
关键字。除非你等待,否则你会得到原始承诺

如此有效地:

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> }
然后,您可以调用
let p=f()
,当您想要获得实际承诺时,可以稍后调用
p()
。这就是JavaScript通常处理延迟执行的方式

如果您希望立即开始履行承诺,您仍然可以满足以下条件:

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

  return () => { p };
}
尽管这些类型的技术通常最好尽可能避免,而且通常是这样。

根据:

异步函数总是返回一个承诺。如果异步函数的返回值不是显式的承诺,它将隐式地包装在承诺中

换言之,既然你在回报一个承诺,它就不会被包装起来。如果你想重新包装它,你可以,但是你也可以去掉具有类似效果的
async
关键字。除非你等待,否则你会得到原始承诺

如此有效地:

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> }
然后,您可以调用
let p=f()
,当您想要获得实际承诺时,可以稍后调用
p()
。这就是JavaScript通常处理延迟执行的方式

如果您希望立即开始履行承诺,您仍然可以满足以下条件:

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

  return () => { p };
}

尽管这类技术通常都是尽可能避免的,而且通常都是这样。

您想要一个
async
函数,在调用
wait
时返回一个承诺吗?还不清楚是什么引起了混乱注意本节:
如果异步函数的返回值不是显式的承诺,它将隐式地包装在承诺中。
。因此,如果返回值已经是一个承诺,则它不会被包装。如果希望将承诺解析为承诺,则必须将内部承诺包装到对象中,以便第一个承诺解析为包含承诺的对象。无论是
Promise.resolve(somePromise)
,从
.then()处理程序返回承诺,还是在
异步
函数中返回承诺,都是如此。这就是它的设计。有趣的是,为什么?它是这样设计的,因为你几乎总是希望承诺链和父母的承诺等待孩子的承诺。不将父承诺和子承诺链接在一起的用例是什么?否。展平可以在每个thenable上工作(使用
.then
方法的对象)。是否需要一个
异步
函数,在调用
wait
时返回承诺?还不清楚是什么引起了混乱注意本节:
如果异步函数的返回值不是显式的承诺,它将隐式地包装在承诺中。
。因此,如果返回值已经是一个承诺,则它不会被包装。如果希望将承诺解析为承诺,则必须将内部承诺包装到对象中,以便第一个承诺解析为包含承诺的对象。无论是
Promise.resolve(somePromise)
,从
.then()处理程序返回承诺,还是在
异步
函数中返回承诺,都是如此。这就是它的设计。有趣的是,为什么?它是这样设计的,因为你几乎总是希望承诺链和父母的承诺等待孩子的承诺。不将父级和子级承诺链接在一起的用例是什么?不。展平可以在每个表上工作(使用
。然后
方法的对象)。@jonaswillms避免这种情况的方法是首先不要造成问题。如果你想要一个原始的承诺,不要使用
async
来声明它,这是违反规则的。。。我认为从问题中可以清楚地看出,这与async/Wait无关。@Jonaswillms“对不起,JavaScript不想这样工作。”我添加了一条说明,说明即使使用
Promise.resolve()
也不会有帮助,因为这样会自动将其展开。关于承诺的一切都是为了实现这一目标而设计的。是的,这就是问题的答案question@JonasWilms避免这种情况的方法是首先不要制造问题。如果你想要一个原始的承诺,不要使用
async
来声明它,这是违反规则的。。。我认为从问题中可以清楚地看出,这与async/Wait无关。@Jonaswillms“对不起,JavaScript不想这样工作。”我添加了一条说明,说明即使使用
Promise.resolve()
也不会有帮助,因为这样会自动将其展开。一切