gpt4 book ai didi

javascript - Angular 数据绑定(bind)不适用于 async/await,但它可以用于 promises

转载 作者:太空狗 更新时间:2023-10-29 17:43:42 25 4
gpt4 key购买 nike

如果数据绑定(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 切换到 ES2015ES2016 TypeScript target 来解决问题

关于javascript - Angular 数据绑定(bind)不适用于 async/await,但它可以用于 promises,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49284122/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com