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

时间:2019-01-29 20:27:18

标签: async-await asyncstorage

我试图从函数中的AsyncStorage获取信息(真/假),并创建一个字符串,该字符串对于下一步获取数据很重要。我的问题是,直到需要字符串后,函数才能完成。

我尝试了互联网上的许多解决方案,例如异步函数,然后等待getItem或.done()或.then(),但没有一个对我有用。

当前的行为是,控制台显示的是“ channel required channel:”而不是“ channel:channel_id0”。

3 个答案:

答案 0 :(得分:0)

如果您将_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匹配的表达式。

答案 1 :(得分:0)

试试看。异步功能和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}`);
    });
}

答案 2 :(得分:0)

您的问题方面尚不清楚:

  1. 您无需说明设置this.state.firstValue的时间以及它与您要实现的目标之间的关系。

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

  3. 变异状态,而不是设置状态。这不好,请参见SO question

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

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

这里是重构:

_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);
}

尽管上面的方法可以工作,但是由于您还不清楚要返回哪个值,因此当前不会返回值。我建议您以我在此处编写的代码为基础,并对其进行更新,以使其返回所需的值。

进一步阅读

为进一步阅读,我建议迈克尔·陈(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的问题都很好

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

Using async/await with a forEach loop