我正在尝试从函数中的 AsyncStorage 获取信息(真/假),并创建一个对于下一步获取数据非常重要的字符串。我的问题是,直到需要字符串时该函数才完成。
我尝试了互联网上的许多解决方案,例如 async function 和 wait getItem 或 .done() 或 .then(),但没有一个适合我。
//_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 this.state.channels;
_fetchData() {
var channel = this._getFetchData();
console.log("channel required: " + channel);
}
当前的行为是控制台首先显示“channel required:”而不是“channel:channel_id0”。
最佳答案
您的问题中的某些方面不清楚:
你没有说何时
this.state.firstValue
已设置,以及它与您想要实现的目标有何关系。您有
for-loop
您可以多次设置相同的值。您改变状态而不是设置它。这不好,看这个SO question了解更多信息。
我们可以采取一些措施来使您的代码更易于理解。下面我将展示一个可能的重构。解释我在每一步中所做的事情。我正在使用async/await
因为它可以使代码更整洁、更容易阅读,而不是使用 promises
您可能会迷失在回调中。
- 从 AsyncStorage 获取所有 key
- 确保所有键都有一个值。
- 过滤键,以便我们只包含不包含字符串
'not'
的键. - 使用
Promise.all
,这部分很重要,因为它基本上获取我们刚刚找到的每个键的所有值并将它们放入名为items
的数组中 -
items
中的每个对象数组有key
和一个value
属性(property)。 - 然后我们过滤
items
这样只有那些带有item.value === 'true'
的留下来。 - 然后我们过滤
items
这样只有那些带有item.value !== 'true'
的保持。 (这可能是可选的,这实际上取决于您想要做什么) - 我们返回什么?您需要添加该部分。
这是重构:
_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/await
的内容。和promises
https://medium.com/@bluepnume/learn-about-promises-before-you-start-using-async-await-eb148164a9c8
最后是这篇文章和关于 Promise.all
的问题都不错
关于react-native - React Native 有没有办法等到函数完成?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54429091/