AsyncStorage.getItem 返回承诺

AsyncStorage.getItem returning promise

所以我尝试使用 AsyncStorage.getItem 获取数据,然后将其传递给 React-native 中的函数。但是当我这样做时,我从我的函数中得到了这个错误 "data.filter is not a function" 。我认为问题可能出在我没有获取数据而是设置了一个 promise。

构造函数:

constructor(props) {
        super(props)

        const getSectionData = (dataBlob, sectionId) => dataBlob[sectionId];
        const getRowData = (dataBlob, sectionId, rowId) => dataBlob[`${rowId}`];

        const ds = new ListView.DataSource({
            rowHasChanged: (r1, r2) => r1 !== r2,
            sectionHeaderHasChanged : (s1, s2) => s1 !== s2,
            getSectionData,
            getRowData,
        });

        let data = AsyncStorage.getItem('connections').then((token) => {
            token = JSON.parse(token);
            return token;
        });            

        const {dataBlob, sectionIds, rowIds} = this.formatData(data);

        // Init state
        this.state = {
            dataSource: ds.cloneWithRowsAndSections(dataBlob, sectionIds, rowIds),
            left: true,
            center: false,
            right: false
        }
    }

函数:

formatData(data) {
    // We're sorting by alphabetically so we need the alphabet
    const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('');

    // Need somewhere to store our data
    const dataBlob = {};
    const sectionIds = [];
    const rowIds = [];

    // Each section is going to represent a letter in the alphabet so we loop over the alphabet
    for (let sectionId = 0; sectionId < alphabet.length; sectionId++) {
        // Get the character we're currently looking for
        const currentChar = alphabet[sectionId];

        // Get users whose first name starts with the current letter
        const users = data.filter((user) => user.nickname.toUpperCase().indexOf(currentChar) === 0);

        // If there are any users who have a first name starting with the current letter then we'll
        // add a new section otherwise we just skip over it
        if (users.length > 0) {
            // Add a section id to our array so the listview knows that we've got a new section
            sectionIds.push(sectionId);

            // Store any data we would want to display in the section header. In our case we want to show
            // the current character
            dataBlob[sectionId] = { character: currentChar };

            // Setup a new array that we can store the row ids for this section
            rowIds.push([]);

            // Loop over the valid users for this section
            for (let i = 0; i < users.length; i++) {
                // Create a unique row id for the data blob that the listview can use for reference
                const rowId = `${sectionId}:${i}`;

                // Push the row id to the row ids array. This is what listview will reference to pull
                // data from our data blob
                rowIds[rowIds.length - 1].push(rowId);

                // Store the data we care about for this row
                dataBlob[rowId] = users[i];
            }
        }
    }

    return { dataBlob, sectionIds, rowIds };
    }

所以我的问题是,一旦我有了承诺,我应该怎么做才能将它传递给我的函数并使这条线工作 const users = data.filter((user) => user.nickname.toUpperCase().indexOf(currentChar) === 0);?

是的,您不是在等待解决 promise,您可以将外部函数转换为异步函数和 await 以解析数据,或者您在 .then 中输入的任何内容在承诺解决后获得 运行。也进入 componentDidMount。您可能还想查看 FlatList 而不是 ListView:

componentDidMount(){ 
  AsyncStorage.getItem('connections').then((token) => {
    const token = JSON.parse(token);           

    const {dataBlob, sectionIds, rowIds} = this.formatData(token);

    // Update State
    this.setState({ 
      dataSource: ds.cloneWithRowsAndSections(dataBlob, sectionIds, rowIds)
    });

  });
}