samshum22
samshum22
  • 发布:2021-05-17 22:07
  • 更新:2021-05-18 12:18
  • 阅读:1065

用 for-loop 去使用 uni.saveFile 及 uni.downloadFile

分类:uni-app

情況是這樣的,
我想做一個APP,
一打開時,會看檔案(mp4/jpg)是否齊全
會先把缺少的檔案放在一個 arrary 里面
然後使用for-loop去下載.
重點在這裡:
在下載之前我會建立一個空的字典

當我下載每所有檔案之後,字典會插入{ "原本檔案名" : "保存檔案名" }
最後一次過把字典用uni.setStorage 更新及保存該字典.

但每當我運行此程序時,
JS都會把 uni.saveFile 及 uni.downloadFile 放在異步queue上另外運行,
所以常常導致最後很多檔案未來得及下載檔案+保存檔案+更新字典,便運行 uni.setStorage 保存了.
想請教大神我應該如何去實現把uni.saveFile 及 uni.downloadFile強行實現同步運行?

暫時試過回調做法和promise.都實現不了(應該是我功力太低)

2021-05-17 22:07 负责人:无 分享
已邀请:
名图客

名图客

1、检查是否齐全,找出需要下载的文件
2、异步并发下载(下面代码)
let downFiles = await Promise.all([
uni.downloadFile,uni.downloadFile,uni.downloadFile
])
3、完后更新保存storage

(你的困惑应该是同步与异步的问题)

  • samshum22 (作者)

    感謝回覆

    2021-05-18 11:50

samshum22

samshum22 (作者)

剛剛自己再啄磨了一下子,果然是自己太嫩了,
是因為由python再學js
python 比較直觀... 剛入手js, 回調函數,異步與同步都未用得純熟就要處理該問題,煩了很幾天
果然真的要再由零學起就會明白得更多

另外想說明,不可使用forEach 去建立promise

以下是我参考了 https://zellwk.com/blog/async-await-in-loops/ 所得出的解:
<button @click="myDownload_btn">myDownload_btn</button>

        myDownload_btn() {  
            let tmpDict = {}  //空字典,用於保存{ "原本檔案名" : "保存檔案名" }  

            const urlList = [ //要下載的url array  
                'https://ns-strategy.cdn.bcebos.com/ns-strategy/upload/fc_big_pic/part-00270-3760.jpg',  
                'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=1947872534,1823906830&fm=26&gp=0.jpg',  
                'https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=1034074796,4011346817&fm=26&gp=0.jpg'  
            ]  

            const myDownload = (url_index) => {  //參考教學的sleep  
                return new Promise(resolve => {  
                    let urlAddress = urlList[url_index]  
                    uni.downloadFile({  
                        url:urlAddress,  
                        success:(res)=>{  
                            console.log('DL sucess,tmpPath = ',res.tempFilePath)  
                            uni.saveFile({  
                                tempFilePath:res.tempFilePath,  
                                success: (savedRes) => {  
                                    tmpDict[url_index] = savedRes.savedFilePath //更新tmpDict的內容  
                                    resolve() //釋放promise鎖<< 我自己定義,python也有類似東西  
                                }  
                            })  
                        }  
                    })  
                })  
            }  
            const myJob = (url_index) => {    //參考教學的getNumFruit   
                return myDownload(url_index).then(v => urlList[url_index])  
            }  
            const control = async _ => {  
                console.log('Start')  
                for (let i = 0;i<3;i++){  
                    let DL_Job = await myJob(i)  
                }  
                console.log(tmpDict)  
                console.log('End')  
            }  

            control() //程序入口  
        },
  • 名图客

    for (let i = 0;i<3;i++){

    let DL_Job = await myJob(i)

    }

    你这是同步,改用为Promise.all异步并发更快。节省等待时间。

    let list = []

    for (let i = 0;i<3;i++){

    list.push(myJob(i))

    } //也可用forEach组合promise 矩阵,异步并发执行。

    let results = await Promise.all(list)

    2021-05-18 13:35

  • 名图客

    forEach本身是回调,回调里面使用promise没有意义。另外,传统的for() 下载,为同步串行,是Promise.all异步并发的n倍(n=promise数量)等待时间

    2021-05-18 13:45

  • samshum22 (作者)

    回复 名图客: 厲害

    2021-05-18 14:46

该问题目前已经被锁定, 无法添加新回复