我一直在寻找2个小时的问题,我的回调函数不会忽略Ionic 2中的LoadingController。
我有一个函数hideLoading():
hideLoading()
{
this.loader.dismiss();
}
在成功函数中调用
connectionSuccess = () =>
{
this.hideLoading();
var toast = Toast.create({
message: '...',
duration: 3000});
this.nav.present(toast);
}
由于某种原因它不起作用..但我发现它有效 - 如果我在其间放置一个警报();或者如果我将代码更改为:
connectionSuccess = () =>
{
this.hideLoading();
this.loader.dismiss();
[...]
}
是否与时间有关?警报()之间的时间或第二个隐藏指令似乎解决了它..我在解雇之前检查了控制台日志中this.loader
的内容,这是完全正确的。
如果我删除上述两条指令中的一条,则无效。它需要两个指令 - 基本上做同样的事情,但只能一起工作..?
这是一个非常脏的修复。我怎么能以干净的方式解决这个问题?我不明白为什么它的行为如此不可预测。
答案 0 :(得分:1)
根据在评论中进行的讨论,我们知道this.Loader
是一个离子角度Loading
类的实例,并且它的dismiss
方法返回,至少在在OP的上下文中运行ZoneAwarePromise
实例。
ZoneAwarePromise
是为 zone.js 创建的专用Promise
实现,Angular依赖该库来破坏DOM并重新连接编排异步回调和事件,但我离题......
重点是它基本上是Promise
,并且明确表示异步 API。我们需要适当地与这样的API交谈,因为在火灾和忘记方式中使用它会导致时间问题,例如OP中指示的行为。
下面我将根据OP的代码说明我认为的正确重写代码。
在TypeScript> = 2.2.0和ES2017中,我们可以利用两种方法来干净利落地正确处理基于承诺的API,并确保相关逻辑的正确执行顺序。
async
/ await
。这可以被认为是与基于Promise的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是基于Promise的,就像这里的那个,那么通过async
/ await
使用它几乎是毫不费力的改变,因为我们甚至可以保留顺序异常处理机制。
如果我们的转换器或运行时没有async
/ await
支持,我们可以使用Promise.prototype.then
和Promise.prototype.catch
来完成相同的目标来编写代码以最小的麻烦完成工作。
如果API基于Observable
,那么我们需要更复杂的转换,并且不能选择使用async
/ await
等语法糖。 1功能
注意:
async
/ await
和 LINQ理解都可直接在Observable
上作为句法糖进行操作。它们可能不是最合适的,但这可能会有所帮助。在JavaScript中,我们没有这样的设施。