簡體   English   中英

JS:異步 function 隱式解包 promise?

[英]JS: async function implicitly unwraps promise?

據我所知,異步函數將其返回值隱式包裝到 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。

請注意,這也適用於顯式創建的 Promise ( Promise.resolve(new Promise(...)) )

有沒有避免這種情況的方法? 我真的很想有一個嵌套的 Promise 沒有這樣的快速修復。

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

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

沙盒

根據關於async函數的 MDN 文檔

異步函數總是返回 promise。 如果異步 function 的返回值不是顯式 promise,它將隱式包裝在 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())
})()

這給了你 output 像:

Promise { <pending> }

如果目標是擁有一個返回原始 Promise 的 Promise,那么您將與 Promise 系統旨在執行的所有事情作斗爭,即它們會自動解開 Promises。 Promise.resolve()包裝了Promise 之外的所有內容,如果你給它一個 Promise 不知何故,它會遞歸地解包。

您可以通過返回不是 Promise 的東西來做到這一點,就像在您的示例中一樣,但這似乎違背了 Promises 的全部目的。

如果您有一個特定的問題,您正在嘗試解決絕對需要延遲 Promise,請考慮返回 function 而不是一些任意的 object:

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

然后,當您想獲得實際的 Promise 時,您可以調用let p = f()和稍后的p() 這就是 JavaScript 通常處理延遲執行的方式。

如果您想立即在 Promise 上啟動執行,您仍然可以適應:

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

  return () => { p };
}

盡管如果可能的話,通常最好避免使用這類技術,而且通常情況下也是如此。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM