【问题标题】:Asynchronous tasks and await calls异步任务和等待调用
【发布时间】:2021-12-14 20:29:30
【问题描述】:

所以我最近一直在思考一些事情,但我自己无法想出任何答案。 想象一下,我们定义了一个解析 Promise 的函数,并使用 await 通过代码多次调用它。 承诺实际上是被多次调用还是只被调用一次并且它的值被多次使用(我们等待函数的地方)?

以身作则:

function readFile(file) {
  //the function returns a promise with value from FileReader.readAsText()
}
let toto = (await readFile("somefile")).concat(" / ", "toto")
let titi= (await readFile("somefile")).concat(" / ", "titi")

readFile() 是实际读取文件两次还是只读取一次?

【问题讨论】:

    标签: javascript asynchronous async-await promise


    【解决方案1】:

    调用函数调用函数。

    await 关心右侧的评估值。

    它不会阻止函数调用成为函数调用。

    您的代码相当于:

    let promise_from_first_call = readFile("somefile");
    let resolved_value_from_first_call = await promise_from_first_call;
    let toto = resolved_value_from_first_call.concat(" / ", "toto")
    
    let promise_from_second_call = readFile("somefile");
    let resolved_value_from_second_call = await promise_from_first_call;
    let titi = resolved_value_from_second_call.concat(" / ", "titi")
    

    由于您正在读取 same 文件两次,您能否通过仅调用该函数一次来提高效率 - 但这是您必须更改的内容,await 不会变魔术给你。

    let file = await readFile("somefile");
    let toto = file.concat(" / ", "toto")
    let titi = file.concat(" / ", "titi");
    

    【讨论】:

      【解决方案2】:

      想象一下,我们定义了一个函数来解析一个 promise,然后我们使用 await 在代码中多次调用它。承诺实际上是被多次调用还是只被调用一次并且它的值被多次使用(我们等待函数的地方)?

      readFile() 是实际读取文件两次还是只读取一次?

      稍微修正词汇:

      • readFile 之类的函数将返回一个 Promise。该 Promise 可能处于 fulfilled (resolved) 或 rejected 状态,或者它可能处于 pending 状态。所有标记为 async 的函数都会自动返回 Promises,无论您是否明确这样做,但非 async 函数也可以返回 Promises。
      • 通常由调用者选择是重用现有的 Promise 还是创建新的 Promise;没有看到readFile,我们无法确定它是否在读取文件两次,但您发布的代码肯定会调用readFile 两次。除非readFile 或操作系统中有任何聪明之处,否则您的文件将被读取两次。
      • 你不能以任何有意义的方式调用一个promise:你可以调用一个像readFile这样的函数,如果它返回一个Promise,你可以链接使用.then(...)或等待在async函数中使用await。
      • Promise 将解决(resolve 或reject)一次,之后永远不会改变状态或值。
      • 您可以在同一个 Promise 上独立地多次调用 .then(...) 或 await。

      因此:

      // readFile is called twice, so the values are not being reused.
      let toto = (await readFile("somefile")).concat(" / ", "toto")
      let titi = (await readFile("somefile")).concat(" / ", "titi")
      
      // readFile is called once. You await the Promise twice here, which is
      // not necessary, but demonstrates a Promise being reused.
      let filePromise = readFile("somefile")
      let toto = (await filePromise).concat(" / ", "toto")
      let titi = (await filePromise).concat(" / ", "titi")
      
      // readFile is called once, and the Promise it returns is awaited once.
      let file = await readFile("somefile")
      let toto = file.concat(" / ", "toto")
      let titi = file.concat(" / ", "titi")
      

      旁注:如果您以任何一种方式结束 Promise,您也许可以使用更新的基于 Blob.text() Promise 的 API。

      【讨论】:

        猜你喜欢
        • 2013-02-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-03-18
        • 2014-09-06
        • 2017-07-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多