我试图从函数中的AsyncStorage获取信息(真/假),并创建一个字符串,该字符串对于下一步获取数据很重要。我的问题是,直到需要字符串后,函数才能完成。
我尝试了互联网上的许多解决方案,例如异步函数,然后等待getItem或.done()或.then(),但没有一个对我有用。
当前的行为是,控制台显示的是“ channel required channel:”而不是“ channel:channel_id0”。
答案 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)
您的问题方面尚不清楚:
您无需说明设置this.state.firstValue
的时间以及它与您要实现的目标之间的关系。
您有一个for-loop
,可以在其中多次设置相同的值。
我们可以做一些事情来使您的代码更容易理解。下面,我将显示一个可能的重构。解释我在每个步骤中所做的事情。我之所以使用async/await
是因为它会导致更整齐,更易于阅读的代码,而不是使用promises
会使您迷失在回调函数中。
'not'
的键。Promise.all
,这一部分很重要,因为它基本上获取了我们刚刚找到的每个键的所有值,并将它们放入名为items
的数组中。items
数组中的每个对象都有一个key
和一个value
属性。 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
的问题都很好