Angular 依赖 Zone.js 进行更改检测,而 Zone.js 通过修补每个可以提供异步行为的 API 来提供此功能。
问题在于如何原生async
功能已实现。正如在这个问题,它们不只是环绕全球Promise
但依赖于不同浏览器可能有所不同的内部机制。
Zone.js 补丁Promise
但不可能修补所使用的内部承诺async
当前引擎实现中的函数(这里是开放问题为了那个原因)。
Usually (async () => {})() instanceof Promise === true
。对于 Zone.js 来说,情况并非如此;async
函数返回一个native实例Promise
, while Promise
global 是由 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));
}
}
Here是一个使用的例子@nativeAsync
装饰器上async
触发变化检测的方法:
@nativeAsync
async getFoo() {
await new Promise(resolve => setTimeout(resolve, 100));
this.foo = 'foo';
}
Here是同一示例,但未使用其他措施来触发更改检测,并且预期不会按预期工作。
在不需要转译步骤的环境中坚持本机实现是有意义的。由于 Angular 应用程序应该以任何方式编译,因此可以通过切换来解决问题ES2017
to ES2015
or ES2016
打字稿target
.