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

前端 未结 3 586
时光取名叫无心
时光取名叫无心 2021-01-24 23:20

I\'m trying to get information (true/false) from AsyncStorage in a function and create a string which is importent to fetch data in the next step. My problem is, the function is

3条回答
  •  无人共我
    2021-01-24 23:57

    Aspects in your question are unclear:

    1. You don't say when this.state.firstValue is set, and how that relates to what you are trying to accomplish.

    2. You have a for-loop where you could be setting the same value multiple times.

    3. You mutate the state rather than set it. This is not good, see this SO question for more on that.

    There are somethings we can do to make your code easier to understand. Below I will show a possible refactor. Explaining what I am doing at each step. I am using async/await because it can lead to much tidier and easier to read code, rather than using promises where you can get lost in callbacks.

    1. Get all the keys from AsyncStorage
    2. Make sure that there is a value for all the keys.
    3. Filter the keys so that we only include the ones that do not contain the string 'not'.
    4. Use a Promise.all, this part is important as it basically gets all the values for each of the keys that we just found and puts them into an array called items
    5. Each object in the items array has a key and a value property.
    6. We then filter the items so that only the ones with a item.value === 'true' remain.
    7. We then filter the items so that only the ones with a item.value !== 'true' remain. (this may be optional it is really dependent on what you want to do)
    8. What do we return? You need to add that part.

    Here is the refactor:

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

    You would call this function as follows:

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

    Although the above will work, it will not currently return a value as you haven't made it clear which value you wish to return. I would suggest you build upon the code that I have written here and update it so that it returns the values that you want.

    Further reading

    For further reading I would suggest these awesome articles by Michael Chan that discuss 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

    I would also suggest taking some time to read up about async/await and promises

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

    And finally this article and SO question on Promise.all are quite good

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

    Using async/await with a forEach loop

提交回复
热议问题