Promise还应该用吗?

时间:2018-03-27 00:13:27

标签: javascript typescript ionic-framework promise

如果是的话 - 怎么样?

我有以下IONIC 3代码,我不知道为什么它的工作原理

首先,有一个所谓的“MusicService”,它负责从本地存储加载音乐文件:

private searchList: string[] = ["sdcard/Music", "sdcard/Download"]

public LoadMusicFromFS(): Promise<void>{
    this.foundMusic = []

    return new Promise((resolve, reject) => {
        this.searchList.forEach((dir)=>{
            this.CheckDir(dir, 0)
        })
    })
}

public foundMusic: Music[] = []
private CheckDir(dir: string, level: number): Promise<void>{
    return this.localFileSystem.listDir("file:///", dir).then((arr)=>{
        arr.forEach((elem)=>{

            if(elem.isDirectory){
                if(!(this.ignoreList.indexOf(elem.fullPath.slice(1, -1))>-1)) this.CheckDir(elem.fullPath.substr(1), level+1)
            }else{
                let fileType: string = elem.name.split(".").pop()
                if(this.searchTypes.indexOf(fileType)>-1){
                    console.log(elem.fullPath + " | " +elem.name+ " --> is Dir? "+elem.isDirectory)
                    let addingMusic: Music = new Music()
                    addingMusic.description.title = elem.name.split(".").slice(0, -1).join(".")
                    addingMusic.media.filePath = elem.fullPath
                    addingMusic.description.album.name="Test"
                    addingMusic.media.length=100



                    this.foundMusic.push(addingMusic)
                }
            }
        })
    }, err => {})
}

还有一个Page,我从服务中调用该函数:

this.platform.ready().then(() =>{
  this.musicService.LoadMusicFromFS().then(()=>{
    // This will never be printed -- why? 
    console.log("Music List successfully loaded")
  })
  // This loads the correct Music, but only because of references
  this.musicCache=this.musicService.foundMusic
})

我真的不明白 - 为什么“当时”部分不在页面中工作?

2 个答案:

答案 0 :(得分:4)

我建议您阅读documentation这有助于您更好地了解承诺的运作方式。

  

执行程序通常启动一些异步工作,然后启动一次   完成后,要么调用resolve函数来解析   如果发生错误,则承诺或拒绝它。如果抛出错误   在执行函数中,承诺被拒绝。的返回值   执行者被忽略了。

您的控制台日志永远不会执行,因为永远不会resolve/reject您的承诺

return new Promise((resolve, reject) => {
  this.searchList.forEach((dir)=>{
    this.CheckDir(dir, 0)
  })
})

您必须致电resolve/reject例如

return new Promise((resolve, reject) => {
  // reject if searchList is empty
  if (this.searchList.length < 1) {
    reject();
  }
  Promise.all(this.searchList.map((dir)=> this.CheckDir(dir, 0))).then(
    () => resolve(),
    () => reject()
  );
})
  

Promise.all(iterable)方法返回一个Promise   当iterable参数中的所有promise都有时,会解析   已解决或当iterable参数不包含promise时。它   拒绝承认拒绝的第一个承诺。

你甚至可以这样做:

public LoadMusicFromFS(): Promise<any[]>{
    this.foundMusic = []

    return Promise.all(this.searchList.map((dir)=> this.CheckDir(dir, 0)));
}

而不是将其包装在另一个承诺中。

答案 1 :(得分:0)

看起来你想要完成的是在checkDir完成后缓存你的结果。

这是有道理的,使用Promise可以使您获益。

但是,在您的代码中:

this.musicCache = this.musicService.foundMusic

foundMusic是一个数组,因此这里的赋值仅指定对该数组this.musicCache的引用(即浅拷贝)。我没有看到这样做的意义。也许您希望this.musicCache成为将文件路径映射到音乐对象的某种地图,或类似的东西?

此外,根据Promise的使用,您可以构造一个值并解析对该值的承诺,然后then(..)它。