- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
如果数据绑定(bind)的值在 await
语句后更改,则数据绑定(bind)不会更新。
handle() {
this.message = 'Works'
}
async handle() {
this.message = 'Works'
}
async handle() {
await new Promise((resolve, reject) => {
resolve()
})
this.message = 'Works'
}
async handle() {
await new Promise((resolve, reject) => {
setTimeout(() => resolve(), 3000)
})
this.message = 'Doesn\'t work'
}
handle() {
new Promise((resolve, reject) => {
setTimeout(() => resolve(), 3000)
})
.then(() => this.message = 'Works')
}
为什么最后两个行为不一样?它们不应该是同一个东西吗?
ionic :3.9.2
Angular :5.0.3
typescript :2.4.2
编辑:我遇到了另一个可能对某些人有用的问题。
在构造函数中更改绑定(bind)值的行为与 ionViewDidLoad 或 ngOnInit 不同!
constructor(private zone: NgZone) {
// This will cause the same problems, bindings not updating
this.handle()
}
constructor(private zone: NgZone) {
// Unless you do this...
this.zone.run(() => {
this.handle()
})
}
ionViewDidLoad() {
// But I think this is better/cleaner
this.handle()
}
最佳答案
Angular 依赖于 Zone.js 进行变化检测,而 Zone.js 通过修补每个可以提供异步行为的 API 来实现这一点。
问题在于 native async
函数是如何实现的。正如在 this question 中确认的那样,它们不只是环绕全局 Promise
,而是依赖于可能因浏览器而异的内部机制。
Zone.js 修补了 Promise
,但不可能修补当前引擎实现中 async
函数使用的内部 promise(这里是 open issue)。
通常 (async () => {})() instanceof Promise === true
。对于 Zone.js,这不是真的; async
函数返回原生 Promise
的实例,而 Promise
global 是由 Zone.js 修补的区域感知 promise 。
为了让原生的 async
函数在 Angular 中工作,应该额外触发变化检测。这可以通过显式触发它(正如另一个答案已经建议的那样)或使用任何区域感知 API 来完成。一个用区域感知 promise 包装 async
函数结果的助手就可以做到这一点:
function nativeAsync(target, method, descriptor) {
const originalMethod = target[method];
descriptor.value = function () {
return Promise.resolve(originalMethod.apply(this, arguments));
}
}
Here是一个在 async
方法上使用 @nativeAsync
装饰器来触发变化检测的例子:
@nativeAsync
async getFoo() {
await new Promise(resolve => setTimeout(resolve, 100));
this.foo = 'foo';
}
Here是相同的示例,它没有使用额外的措施来触发更改检测,并且预计不会按预期工作。
在不需要转译步骤的环境中坚持 native 实现是有意义的。由于 Angular 应用程序应该以任何方式编译,因此可以通过从 ES2017
切换到 ES2015
或 ES2016
TypeScript target 来解决问题
。
关于javascript - Angular 数据绑定(bind)不适用于 async/await,但它可以用于 promises,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49284122/
我是一名优秀的程序员,十分优秀!