如果是的话 - 怎么样?
我有以下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
})
我真的不明白 - 为什么“当时”部分不在页面中工作?
答案 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(..)
它。