有没有办法等到功能完成?

Is there a way to wait until a function is finished?

我试图在一个函数中从 AsyncStorage 获取信息 (true/false) 并创建一个字符串,该字符串对于下一步获取数据很重要。我的问题是,函数在需要字符串之前不会完成。

我尝试了互联网上的许多解决方案,例如异步函数和 await getItem 或 .done() 或 .then(),但 none 对我有用。

当前的行为是控制台首先显示 "channel required: " 而不是 "channel: channel_id0"。

如果将 _getFetchData() 包装在 Promise 中会怎样?这将使您能够使用

var channel = this._getFetchData().then(console.log("channel required: " + channel));

否则 console.log 不会等待 _getFetchData() 的执行。 这就是 console.log 告诉你的。它只是记录字符串。异步操作完成后添加变量。

更新

我会试试这个:

//_getFetchData()
AsyncStorage.getAllKeys().then((result) => { //get all stored Keys
  valuelength = result.length;
  if (valuelength !== 0) {
    for (let i = 0; i < valuelength; i++) {
      if (result[i].includes("not") == false) { //get Keys without not
        AsyncStorage.getItem(result[i]).then((resultvalue) => {
          if (resultvalue === 'true') {
            if (this.state.firstValue) {
              this.state.channels = this.state.channels + "channel_id" + result[i];
              console.log("channel: " + this.state.channels);
            }
            else {
              this.state.channels = this.state.channels + "channel" + result[i];
            }
          }
        });
      }
return new Promise((resolve, reject) => {
    this.state.channels !=== undefined ? resolve(this.state.channels) : reject(Error('error '));
}

_fetchData() {
var channel = this._getFetchData().then(console.log("channel required: " + channel));
}

也许您必须将 this.state.channels !=== undefined 更改为与默认值 this.state.channels 匹配的表达式。

试试这个。异步函数和 Promises 可能很难做到正确并且可能难以调试,但您走在正确的轨道上。

async _getFetchData() {
    let channels = "";

    let results = await AsyncStorage.getAllKeys();

    results.forEach((result) => {
        if (result.includes("not") === false) {
            let item = await AsyncStorage.getItem(result);

            if (item === 'true') {
                console.log(`channel: ${result}`)

                channels = `channel_id ${result}`;
            }
        }
    });

    return channels;
}

_fetchData() {
    this._getFetchData().then((channels) => {
        console.log(`channel required: ${channel}`);
    });
}

你问题中的几个方面不清楚:

  1. 你没有说 this.state.firstValue 是什么时候设置的,以及它与你想要完成的事情有什么关系。

  2. 您有一个 for-loop 可以多次设置相同的值。

  3. 改变状态而不是设置它。这不好,请参阅此 了解更多信息。

我们可以做一些事情来让您的代码更容易理解。下面我将展示一个可能的重构。解释我在每个步骤中所做的事情。我使用 async/await 是因为它可以使代码更整洁、更易于阅读,而不是使用 promises,因为这样您可能会迷失在回调中。

  1. 从 AsyncStorage 获取所有密钥
  2. 确保所有键都有一个值。
  3. 过滤键,以便我们只包含不包含字符串 'not'.
  4. 的键
  5. 使用 Promise.all,这部分很重要,因为它基本上获取了我们刚刚找到的每个键的所有值,并将它们放入一个名为 items
  6. 的数组中
  7. items 数组中的每个对象都有一个 key 和一个 value 属性.
  8. 然后我们过滤 items 以便只保留带有 item.value === 'true' 的。
  9. 然后我们过滤 items 以便只保留 item.value !== 'true' 的。 (这可能是可选的,它实际上取决于你想做什么)
  10. 我们return做什么?您需要添加该部分。

重构如下:

_getFetchData = async () => {
  let allKeys = await AsyncStorage.getAllKeys();                             // 1
  if (allKeys.length) {                                                      // 2

    let filteredKeys = allKeys.filter(key => !key.includes('not'));          // 3
    let items = await Promise.all(filteredKeys.map(async key => {            // 4
      let value = await AsyncStorage.getItem(key);
      return { key, value };                                                 // 5
    }))

    let filteredTrueItems = items.filter(item => items.value === 'true');    // 6
    let filteredFalseItems = items.filter(item => items.value !== 'true');   // 7
    // now you have two arrays one with the items that have the true values 
    // and one with the items that have the false values
    // at this points you can decide what to return as it is not 
    // that clear from your question

    // return the value that your want                                       // 8
  } else {
    // return your default value if there are no keys                        // 8
  }
}

您可以按如下方式调用此函数:

_fetchData = async () => {
  let channel = await this._getFetchData();
  console.log("channel required: " + channel);
}

虽然上面的方法可行,但它目前 return 不是一个值,因为您还没有明确表示要 return 哪个值。我建议您以我在此处编写的代码为基础进行更新,使其 return 成为您想要的值。

进一步阅读

如需进一步阅读,我会推荐这些由 Michael Chan 撰写的精彩文章,其中讨论了 state

https://medium.learnreact.com/setstate-is-asynchronous-52ead919a3f0

https://medium.learnreact.com/setstate-takes-a-callback-1f71ad5d2296

https://medium.learnreact.com/setstate-takes-a-function-56eb940f84b6

我还建议花一些时间阅读有关 async/awaitpromises

的内容

https://medium.com/@bluepnume/learn-about-promises-before-you-start-using-async-await-eb148164a9c8

最后 Promise.all 上的这篇文章和 SO 问题非常好

https://www.taniarascia.com/promise-all-with-async-await/