【问题标题】:JavaScript Async/Await console.log() on array returns empty数组上的 JavaScript Async/Await console.log() 返回空
【发布时间】:2020-01-22 22:15:57
【问题描述】:

您好 Stack Overflow 社区, 我来找你一个与 JS async/await 相关的问题。我正在尝试调用异步函数,然后将数组记录到异步函数将结果推送到控制台的位置。如果我直接在控制台中这样调用它:

console.log(Page.data) - 我可以看到它有结果,但是如果在单击按钮时调用它,它会记录一个空数组。

// It is a nested object so do not worry if you don't exactly understand where Page.data comes from
Page.data = []

async function f1() {
  // Fetch JSON data
  // Process data 
  // Pushes at some point to the Page.data array
}
async function f2() {
  // Fetch JSON data
  // Process data 
  // Pushes at some point to the Page.data array
}
async function f3() {
  // Fetch JSON data
  // Process data 
  // Pushes at some point to the Page.data array
}

async function load(loader) {
    let fn = async function() {};
    if(condition1) fn = f1;
    else if(condition2) fn = f2;
    else fn = f3;

    // This is the line that makes me problems
    // According to documentation async functions return a promise
    // So why would the array in the case be empty?
    // Since I am telling it to display after the function is done
    await fn(loader).then(console.log(Page.data))
}

这只是我的代码和逻辑的模板。我希望你能明白我要去哪里。 非常感谢您的帮助。

【问题讨论】:

  • 您可以使用await 一个promise 来获取分辨率值,或者使用promise.then(...) 以便在promise 解决后启动代码。选择其中之一,而不是两者。
  • @Mike'Pomax'Kamermans 所以你建议我应该做 fn().then()?
  • await fn(loader); console.log(Page.data);
  • 既然你使用了 await 关键字,那么你可以这样做:await fn(loader); console.log(Page.data);
  • 或者只是不使用 await 关键字,它可能会起作用

标签: javascript asynchronous async-await


【解决方案1】:

await 表达式会导致异步函数执行暂停,直到 Promise 被解决(即完成或拒绝),并在完成后恢复异步函数的执行。恢复时,await 表达式的值是已实现的 Promise 的值。

例如(这是一个添加了一些 cmets 的 MDN 示例):

function resolveAfter2Seconds(x) { 
  return new Promise(resolve => {
    setTimeout(() => {
      resolve(x);
    }, 2000);
  });
}

async function f1() {
  // note that here, you are "awaiting" the RESOLVED RESULT of the promise.
  // there is no need to "then" it.
  var x = await resolveAfter2Seconds(10);
  // the promise has now already returned a rejection or the resolved value. 
  console.log(x); // 10
}

f1();

因此,您将“等待”您的函数,这将暂停执行,直到 promise 解决或拒绝。在该行之后,您将运行您的 console.log,它会按预期记录。简短的回答,“删除 then”。

我应该补充一点,如果“等待”函数的结果不是一个承诺,它会被转换为一个承诺(所以从技术上讲,不需要返回一个承诺,它会为你包装你的返回值)。

【讨论】:

    【解决方案2】:

    问题是您可以将thenawait 用于相同的方法,让我们查看MDN 提供的一些示例:

    这是一个使用async/await的工作Promise

    let myFirstPromise = new Promise((resolve, reject) => {
      setTimeout(function() {
        resolve("Success!");
      }, 250)
    })
    
    const functionCaller = async() => {
      const result = await myFirstPromise
      console.log("the result: ", result);
    }
    
    functionCaller();

    你正在尝试的是:

    let myFirstPromise = new Promise((resolve, reject) => {
      setTimeout(function() {
        resolve("Success!");
      }, 250)
    })
    
    const functionCaller = async() => {
      // you are not returning anything here... actually you are not doing anything with the response. despite it shows something, it is not sending any response
      await myFirstPromise.then(console.log("something happened"))
    
    }
    // then this function doesn't really get a value.
    functionCaller();

    所以你需要在load 调用中做如下更改:

    async function load(loader) {
        let fn = async function() {};
        if(condition1) fn = f1;
        else if(condition2) fn = f2;
        else fn = f3;
    
        return await fn(loader)
    }
    

    【讨论】:

    • 不错,这确实值得一试。
    猜你喜欢
    • 2017-10-21
    • 2020-07-14
    • 2021-08-06
    • 2017-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-15
    • 1970-01-01
    相关资源
    最近更新 更多