【问题标题】:JavaScript - replace setTimeout with async / awaitJavaScript - 用 async / await 替换 setTimeout
【发布时间】:2020-06-11 01:05:30
【问题描述】:

首先,我知道这是一个常见问题。我正在尝试了解如何使用 async / await 代替 setTimeouts,但是我在网上看到的所有示例都使用 setTimeout 来模拟异步。当我尝试替换设置的超时时,这会让我失望。

在下面的函数中,我希望 this.filteredResults 在尝试过滤这些结果并将其分配给 this.filteredResults 之前等待 API 调用的结果。

getResults() {
  let allResults= airtableQuery.getTable("Transfers"); // API call using imported 'getTable' function

  console.log(allResults); // returns full array ▶[] although it's not available for filtering yet.

  setTimeout(() => { // I want to replace this timeout
    this.filteredResults = allResults.filter(
      (result) => result.fields.User === "dev"
    );
  }, 250); // random ms that is roughly how long airtableQuery takes for the API call.
},

还有airtableQuery:

getTable(table) {
  let recordsArr = [];
  base(`${table}`)
    .select({
      maxRecords: 8000,
    })
    .eachPage(
      function page(records, fetchNextPage) {
        records.forEach((record) => {
          recordsArr.push(record);
        });
        fetchNextPage();
      },
      function done(err) {
        if (err) {
          this.$toasted.error(err);
        }
      }
    );
  return recordsArr;
},

【问题讨论】:

  • 您需要提供airtableQuery.getTable() 的语义,以便任何人都能写出体面的答案。
  • 您经常在有关 Promise 的问题中看到 setTimeout 的原因是因为它是一种创建异步运行的简单方法。大多数异步功能都涉及外部服务器。
  • @RobbyCornelissen - 如果我们只是想在有限的信息中给出解决方案,那么对每个答案都投反对票的目的是什么。如果getTable() 是实际的PromiseAsync/await 就可以正常工作,因为它可以从最初的问题中指出。
  • @RobbyCornelissen 在大多数情况下会立即生效。我看不出如此消极的原因。您可以随时在答案下方的评论部分中根据附加信息编辑答案,直到您正确为止。
  • @RobbyCornelissen 正确,那是我的错。因此,我立即对其进行了编辑。我很抱歉。

标签: javascript asynchronous ecmascript-6 async-await


【解决方案1】:

在过滤结果之前,请将外部函数设为async 函数,然后将结果设为await

async function getResults() {
      let allResults = await airtableQuery.getTable("Transfers");
       this.filteredResults = allResults.filter(
         (result) => result.fields.User === "dev"
       );
},

鉴于getTable() 不是Promiseawait 不会做任何事情。出于这个原因,我们可以让getTable() 返回一个Promise,它将使用recordsArr 解析。

getTable(table) {
    return new Promise((resolve, reject) => {
        let recordsArr = [];
        base(`${table}`)
            .select({
                maxRecords: 8000,
            })
            .eachPage(
                function page(records, fetchNextPage) {
                    records.forEach((record) => {
                        recordsArr.push(record);
                    });
                    fetchNextPage();

                },
                function done(err) {
                    if (err) {
                        this.$toasted.error(err);
                        reject(err)
                    }else {
                        resolve(recordsArr)
                    }
                }
            );
    })
}

希望对你有帮助。

【讨论】:

  • 谢谢。我实际上尝试过,当我 console.log(allResults.length); 它仍然说零长度。
  • 我很感激。我希望我没有让你太紧张。再次道歉 - 感谢您让我受益匪浅。
  • 啊,别担心我。我 10,000% 不值得:P 很高兴我们可以一起工作并为这个问题找到一个公认的答案。
  • 哈哈 :P 你很好,伙计。是的,我们最终做对了,呸……
【解决方案2】:

我总是喜欢 primise,这是我的代码向你展示的

getTable(table) {
    return new Promise((res, rej) => {
        let recordsArr = [];
        base(`${table}`)
            .select({
                maxRecords: 8000,
            })
            .eachPage(
                function page(records, fetchNextPage) {
                    records.forEach((record) => {
                        recordsArr.push(record);
                    });
                    fetchNextPage();
                    res(recordsArr)
                },
                function done(err) {
                    if (err) {
                        this.$toasted.error(err);
                        rej(err)
                    }
                }
            );
    })
}
getResults() {
  airtableQuery.getTable("Transfers").then(res => {
    let allResults = res
    console.log(allResults);
    this.filteredResults = allResults.filter(
      (result) => result.fields.User === "dev"
    );
  }); 
}

【讨论】:

  • 我想你很接近了。可能只需要解决已完成的承诺。 @KirkRoss eachPage() 是什么 API 的一部分?是否需要 3 个回调(数据、错误、完成)?
  • @RobbyCornelissen 我不确定。 eachPage() 是 airtable.js 库的一部分。最后,Jakub 的回答最终奏效了,但感谢您的周到回复。
猜你喜欢
  • 1970-01-01
  • 2019-06-12
  • 1970-01-01
  • 1970-01-01
  • 2016-01-22
  • 1970-01-01
  • 2019-08-11
相关资源
最近更新 更多