ovg*_*ovg 4 javascript data-binding async-await typescript angular
如果数据绑定的值在await语句后更改,则不会更新。
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')
}
Run Code Online (Sandbox Code Playgroud)
为什么最后两个行为不一样?他们不应该是同一件事吗?
离子性:3.9.2
角度:5.0.3
打字稿:2.4.2
编辑:我遇到了与此有关的另一个问题,可能对某些人有用。
在构造函数中更改绑定的值的行为与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()
}
Run Code Online (Sandbox Code Playgroud)
Angular依靠Zone.js进行更改检测,Zone.js通过修补可以提供异步行为的每个API来提供此功能。
问题在于如何async实现本机功能。正如这个问题所证实的那样,它们不仅仅围绕全局,Promise还依赖于可能因浏览器而异的内部机制。
Zone.js进行了修补,Promise但无法修补async当前引擎实现中函数使用的内部诺言(此处是未解决的问题)。
通常(async () => {})() instanceof Promise === true。对于Zone.js,情况并非如此;async函数返回native的实例Promise,而Promiseglobal是Zone.js修补的区域感知承诺。
为了使本机async函数在Angular中工作,应该另外触发更改检测。可以通过显式触发它(如另一个答案已经建议的)或使用任何可识别区域的API来完成。一个将async功能结果与区域感知的承诺包装在一起的助手将达到目的:
function nativeAsync(target, method, descriptor) {
const originalMethod = target[method];
descriptor.value = function () {
return Promise.resolve(originalMethod.apply(this, arguments));
}
}
Run Code Online (Sandbox Code Playgroud)
这是一个@nativeAsync在async方法上使用decorator 触发更改检测的示例:
@nativeAsync
async getFoo() {
await new Promise(resolve => setTimeout(resolve, 100));
this.foo = 'foo';
}
Run Code Online (Sandbox Code Playgroud)
这是一个相同的示例,它没有使用其他措施来触发更改检测,并且预期无法按预期运行。
在不需要转译步骤的环境中坚持本地实施是有意义的。由于Angular应用程序应该以任何方式进行编译,因此可以通过从ES2017to ES2015或ES2016TypeScript 切换来解决问题target。
就像 estus 说的,目前zone.js不支持原生 async/await,所以你不能编译目标到 的打字稿ES2017,我正在研究它,https://github.com/angular/zone.js/pull/795,我已经做了一个可以在 nodejs 中运行的工作演示,但是在浏览器(chrome)中,它仍然需要一些时间,因为 chrome 暂时没有打开 AsyncHooks 和 PromiseHooks 的 javascript 版本。
| 归档时间: |
|
| 查看次数: |
2991 次 |
| 最近记录: |