【发布时间】:2018-01-19 11:50:48
【问题描述】:
我已经在网上搜索了很长一段时间了。
我正在为 Ionic 应用程序制作 Angular 服务的原型。此服务的目的是下载图像。现在这是一个问题,在标准 JS 中,我想通过一些递归调用来解决,以避免重复代码。
我尝试使用 Promise 来编写它,以使我对 Promises 的概念感兴趣,这让我很难过。
考虑以下代码:
public getBgForName = (name: string) => {
name = name.toLowerCase();
var instance = this;
var dir = this.file.dataDirectory;
return new Promise(function (fulfill, reject) {
instance.file.checkDir(dir, name).then(() => {
// directory exists. Is there a bg file?
dir = dir + '/' + name + '/';
instance.file.checkFile(dir, 'bg.jpg').then(() => {
console.log('read file');
fulfill(dir + '/' + 'bg.jpg')
}, (err) => {
// dl file and re-call
console.log('needs to download file!')
instance.transfer.create().download(encodeURI('https://host.tld/'+name+'/bg.jpg'), dir + 'bg.jpg', true, {})
.then((data) => {
return instance.getBgForName(name).then((url) => {return url});
}, (err) => {
console.log(err)
})
})
}, (err) => {
// create dir and re-call
instance.file.createDir(dir, name, true).then(() => {
instance.getBgForName(name).then((url) => {fulfill(url)});
})
})
});
}
当被调用时,承诺永远不会完全解决。我认为,在阅读this article 之后,问题在于我的承诺解决没有正确传递给“原始”承诺链 - 因此它解决了解决水平,但不是一直到顶部。当保证以下内容时,promise 支持正确解析:
目录已经创建
文件已下载
所以我认为 return 语句以某种方式破坏了此处的链接,导致在第一次递归调用后未解决承诺。
什么是递归调用promise的正确方法,确保原始调用者在准备好时收到结果?
编辑:按照 David B. 代码应该是在项目列表上调用的函数。对于每个项目,都有一个可用的背景图像,该图像存储在服务器上。此背景图像将在本地缓存。此处使用递归调用的目的是,无论状态如何(已下载,未下载),函数调用都将始终返回本地文件系统上图像的 url。具体步骤如下:
- 为当前项目创建目录
- 下载文件到这个目录
- 返回下载文件的本地 URL
此后的后续调用只会直接从磁盘返回图像(在检查它是否存在之后),不再下载。
【问题讨论】:
-
更重要的是,你想做什么?您能否像“1. 检查目录是否存在。2. 如果不存在,请执行此操作.. 等等等等”那样概述所需的结果。以这种方式理解和重构代码会容易得多! :)
-
有什么理由不使用
async/await? TypeScript 与递归async/await一起正常工作。 -
@DanielB 我补充了,谢谢。
-
@AkashKava 我将不得不阅读这一点,感谢您的提示。
标签: javascript typescript recursion ionic-framework es6-promise