【发布时间】:2019-08-09 22:44:17
【问题描述】:
您好,我正在编写一个从 Android 版本 4.4.4 到 最新 的 react 本机应用程序。我有一种情况需要下载 数百万 条记录,然后存储到本地数据库 (using watermelon DB)。我正在对记录进行分页并使用 xhr 请求获取数据(一次 10000 个)。
获取和存储都是异步操作。我可以使用循环或递归来做到这一点。
递归片段:
dataFetch = async () => {
if (maxPages && page > maxPages) {
return true;
}
const { data } = await axios.get(API_GET_RECORDS, {
params: {
page,
per_page: 10000,
},
});
if (data.data && data.data.length === 0) {
return true;
}
await addIntoDatabase(this.props.database, data.data);
if ((maxPages || data.max_pages) && page) {
this.setState({
message: `Loading ${Number.parseFloat(
(page * 100) / (maxPages || data.max_pages),
)}%`,
});
// console.log((page * 100) / (maxPages || data.max_pages));
}
return this.dataFetch(page + 1, data.max_pages);
};
循环片段
dataFetch = async () => {
let page = 1;
let maxPages;
do {
const { data } = await axios.get(API_GET_RECORDS, {
params: {
page,
per_page: 10000,
},
});
await addIntoDatabase(this.props.database, data.data);
if (data.max_pages && page) {
this.setState({
message: `Loading ${Math.round((page * 100) / data.max_pages)}%`,
});
}
page += 1;
maxPages = data.max_pages;
} while (page < maxPages);
};
函数调用
downloadMyDataAndDoOtherTask = () => {
// ... some task
dataFetch(); // you should get all the data then start executing next line
// ... some other task depends on this task;
}
在这种情况下最好的方法循环或递归是什么?
当我们在任何类型的循环或递归中执行 setState 时,它不会立即更新 (Batch update concept)。如果我想在这种情况下显示一些进度百分比,我该如何显示。因为 react 不会在所有迭代中更新,所以进度会落后于实际进度。
提前致谢。
编辑
两种方式(循环和递归)在下载大约 2-3 次缺少数据后应用程序都崩溃了。
【问题讨论】:
-
由于您希望所有记录都存储在本地数据库中,您是否考虑过将数据库表导出到文件中并从客户端应用程序下载该文件。并读取该文件并在其上循环,并将记录存储到数据库中。您可以显示下载文件的进度。
-
这也是个好主意。我也想到了这一点,但是时间少了,而且我在使用 react native 处理文件方面没有太多经验,我认为现在不要碰。但是感谢您的建议将在未来实施,但您现在有任何设置状态的解决方案吗?
-
另外,文件对于后端效率不高,因为每个用户的数据不同,因此每个 api 调用服务器都必须生成文件。
标签: javascript reactjs react-native memory-leaks