首页 > 解决方案 > 使用 Expo.Filesystem.downloadAsync 下载大量文件有时会无限期卡住

问题描述

我使用 Expo.Filesystem.downloadAsync 下载大号。图像和视频等文件。但它有时会在某个时刻无限期地卡住。我想在一个循环中下载文件。代码是:

        let image_downloading = section.map(async (item, i) => {
            item.image !== null  ?
                await FileSystem.downloadAsync(item.image,
                    directory + item.image.split("/").reverse()[0]
                )
                    .then(({ uri }) => {
                        item['image'] = uri;
                        console.log('Finished downloading section to ', uri);
                    })
                    .catch(({error}) => {
                        console.log('errorrrrrrrrrrrrr',error)
                    })
                : null
    });
    await Promise.all(image_downloading);

我也尝试过使用 FileSystem.createDownloadResumable。使用 createDownloadResumable 时,下载速度非常慢

标签: androidreact-nativeexpo

解决方案


实际问题出在我发送下载文件请求的服务器上。

它一次冻结大量请求。

所以我改变了我的功能,一次只发送 20 个请求,并在发送下一个 20 个之前等待一秒钟。

首先,我将数组拆分为相同大小的块

let item_chunk_size = 20;
let itemArray = [];
for (let i = 0;i<items.length; i+= item_chunk_size)  {
    let myChunk = items.slice(i, i+item_chunk_size);
    itemArray.push(myChunk)
}

然后通过一次发送 20 个请求来下载图像

for (let i=0;i<itemArray.length;i++){
    let itemChunk = itemArray[i].map(async item => {
        if(item.image !== '' && item.image){
            await FileSystem.downloadAsync(
                item.image,
                directory + item.image.split("/").reverse()[0]
            )
                .then(({uri}) => {
                    this.setState({count:this.state.count+1});
                    item['image'] = uri;
                    console.log('Finished downloading section to ', uri);
                })
        }
        if(item.video !== '' && item.video){
            await FileSystem.downloadAsync(
                item.video,
                directory + item.video.split("/").reverse()[0]
            )
                .then(({uri}) => {
                    this.setState({count:this.state.count+1});
                    item['video'] = uri;
                    console.log('Finished downloading section to ', uri);
                })
        }
    });
    await Promise.all(itemChunk);
    await this.wait(1000);
}

20 个请求后等待一秒的功能

 wait = async(ms) => {
    return new Promise(resolve => {
        setTimeout(resolve, ms);
    })
}

推荐阅读