Javascript 为什么我需要键入两次此命令才能在Typescript,Ionic 2中工作?
我已经搜索了两个小时的问题,我的回调函数并没有关闭离子2中的LoadingController 我有一个函数,hideLoading(): 在success函数中调用Javascript 为什么我需要键入两次此命令才能在Typescript,Ionic 2中工作?,javascript,typescript,ionic-framework,ionic2,Javascript,Typescript,Ionic Framework,Ionic2,我已经搜索了两个小时的问题,我的回调函数并没有关闭离子2中的LoadingController 我有一个函数,hideLoading(): 在success函数中调用 connectionSuccess = () => { this.hideLoading(); var toast = Toast.create({ message: '...', duration: 3000}); this.nav.present(toast);
connectionSuccess = () =>
{
this.hideLoading();
var toast = Toast.create({
message: '...',
duration: 3000});
this.nav.present(toast);
}
由于某种原因,它不起作用。。但我刚刚发现它是有效的——如果我在两者之间加上一个alert();或者,如果我将代码更改为:
connectionSuccess = () =>
{
this.hideLoading();
this.loader.dismiss();
[...]
}
这是与时间有关的错误吗?alert()的时间介于两者之间或第二条hide指令似乎可以解决此问题。。在解散之前,我在控制台日志中检查了this.loader
的内容,它完全正确
如果我删除上面两个说明中的一个,它将不起作用。它需要两个指令——它们基本上做相同的事情,但只是一起工作
这是一个相当肮脏的补丁。我怎样才能以干净的方式解决这个问题?我不明白为什么它的行为如此不可预测。根据在评论中进行的讨论,我们知道
this.Loader
是一个ionic angular加载类的实例,它的dislose
方法返回一个ZoneAwarePromise
实例,至少在OP的上下文中运行时是这样
ZoneAwarePromise
是一个专门的Promise
实现,它是为zone.js创建并由其返回的,Angular依赖该库来破坏DOM并重新编排回调和事件的异步编排,但我偏离了主题
关键是它基本上是一个承诺
,并且明确表示一个异步API。我们需要适当地与这样一个API进行对话,例如在火中使用它,而忘记方式可能会导致时间问题,例如OP中所指示的行为
下面我将根据OP的代码说明我认为正确的代码重写
在TypeScript>=2.2.0和ES2017中,我们可以利用两种方法干净、正确地处理基于承诺的API,并确保相关逻辑的正确执行顺序
异步
/等待
。这可以被认为是未来与基于承诺的API交互的首选方式,因为它提供了优异的可读性,并允许标准的异常处理模型。它也是非常简洁和愉快的写作
export default class {
async hideLoading() {
// note we probably don't need the try wrapper
// it is good practice to NOT handle unknown errors
// just put it here for illustrative purposes
try {
await this.loader.dismiss();
}
catch (e) {
console.error(e);
}
}
connectionSuccess = async () => {
await this.hideLoading();
const toast = Toast.create({
message: '...',
duration: 3000
});
this.nav.present(toast);
};
}
在旧版本的TypeScript中,async
/await
仅支持--target es2015
。如果我们需要将es5
作为目标,并且有一个旧版本的TypeScript无法升级(如果可能的话,您真的应该升级),那么我们可以用以下方式编写具有相同语义的上述代码
export default class {
hideLoading() {
// note we probably don't need the .catch call
// it is good practice to NOT handle unknown errors
// just put it here for illustrative purposes
return this.loader.dismiss()
.catch(e => console.error(e));
}
connectionSuccess = () => {
this.hideLoading()
.then(() => {
const toast = Toast.create({
message: '...',
duration: 3000
});
this.nav.present(toast);
});
};
}
这里的要点是,当我们谈论异步API时,我们必须使用异步编程模型。如果API是基于承诺的,比如这里的API,那么通过async
/await
使用它几乎是一个毫不费力的更改,因为我们甚至可以保留顺序异常处理机制
如果我们在transpiler或运行时中都没有async
/await
支持,那么我们可以使用Promise.prototype.then
和Promise.prototype.catch
来编写代码,以尽可能少的麻烦完成任务
如果API是基于可观察的
,那么我们将需要更复杂的转换,并且不能选择使用语法糖,例如async
/await
.1
注:
在RxJS的源语言C#和Visual Basic中,异步
/等待
和LINQ理解都可以直接在可观察
上作为语法糖进行操作。它们可能并不完美,但这可能会有所帮助。在JavaScript中,我们没有这样的功能
这个.loader
是什么,调用会在返回时忽略它什么<代码>未定义
?一个承诺
?可观察到的
?您可能缺少一个wait
、一个return
、一个subscribe
,但从提供的信息很难判断。@AluanHaddad这个。loader
是ionic 2的加载
类的一个实例。dislose()
方法返回ZoneAwarePromise{…}
。Await听起来不错,但我在方法调用前面放置Await时遇到语法错误。这似乎确实是一个异步/等待问题,因为在两者之间放置警报可以解决此问题。。编辑:我尝试了alert(),但它不再修复它。。但就在之前,它在之间使用了一个alert()。好吧,它返回一个承诺,然后使用async hideLoading(){wait this.loader.dismise();}
然后需要在调用hideLoading
的方法中等待它。您还可以使用然后
并显式返回结果。wait是更可读的选项。仅供参考,alert工作的原因可能是alert是一种罕见的浏览器API,它实际上会阻止事件循环。不确定原因,可能您没有使用最新的TypeScript(使用>=2.2.1)。无论如何,您可以不用异步
/等待
和完成相同的任务。然后
和捕获
这对我来说很有效,非常感谢!我不知道应该如何使用.then(),但现在它很有意义。很高兴我能帮上忙
export default class {
hideLoading() {
// note we probably don't need the .catch call
// it is good practice to NOT handle unknown errors
// just put it here for illustrative purposes
return this.loader.dismiss()
.catch(e => console.error(e));
}
connectionSuccess = () => {
this.hideLoading()
.then(() => {
const toast = Toast.create({
message: '...',
duration: 3000
});
this.nav.present(toast);
});
};
}