Angular 数据绑定不能与 async/await 一起使用,但可以与 Promise 一起使用

2023-11-24

如果数据绑定的值在某个时间后发生更改,则数据绑定不会更新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')
  }

为什么最后两个的行为不一样?它们不应该是同一件事吗?

离子: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()
  }

Angular 依赖 Zone.js 进行更改检测,而 Zone.js 通过修补每个可以提供异步行为的 API 来提供此功能。

问题在于如何原生async功能已实现。正如在这个问题,它们不只是环绕全球Promise但依赖于不同浏览器可能有所不同的内部机制。

Zone.js 补丁Promise但不可能修补所使用的内部承诺async当前引擎实现中的函数(这里是开放问题为了那个原因)。

Usually (async () => {})() instanceof Promise === true。对于 Zone.js 来说,情况并非如此;async函数返回一个native实例Promise, while 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));
  }
}

Here是一个使用的例子@nativeAsync装饰器上async触发变化检测的方法:

  @nativeAsync
  async getFoo() {
    await new Promise(resolve => setTimeout(resolve, 100));
    this.foo = 'foo';
  }

Here是同一示例,但未使用其他措施来触发更改检测,并且预期不会按预期工作。

在不需要转译步骤的环境中坚持本机实现是有意义的。由于 Angular 应用程序应该以任何方式编译,因此可以通过切换来解决问题ES2017 to ES2015 or ES2016打字稿target.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Angular 数据绑定不能与 async/await 一起使用,但可以与 Promise 一起使用 的相关文章

  • Javascript 进程是否有多个执行线程?

    背景 我正在创建一个 地址簿 类型的应用程序 有很多条目需要加载 一个想法是首先加载一小部分条目 让用户开始 然后将剩余条目排队 优先考虑用户单击的条目 例如 如果他们单击以 X 开头的名称 请先加载这些名称 然后再处理队列的其余部分 这个
  • 有没有一种方法可以在没有输入的情况下发送表单值

    假设我有以下表格
  • 获取异常 jQuery 必须包含在 Bootstrap 的 JavaScript 之前

    我遇到以下异常 bootstrap js 240 Uncaught TypeError Bootstrap 的 JavaScript 需要 jQuery jQuery 必须包含在 Bootstrap 的 JavaScript 之前 在 Ob
  • 使用函数重载进行解构

    我正在尝试创建一个函数 该函数需要一对坐标或一个对象x and y属性并返回邻居列表 但由于某种原因 即使我检查了它的类型 我也无法解构该对象 interface Coords x number y number public getNei
  • 使用 jQuery inputmask 插件范围 0-100

    如何创建 0 到 100 范围内的掩码 document ready function masked inputmask 您可以使用jquery inputmask regex extensions js为了那个原因 你可以找到带有所有扩展
  • 如何将 Angular Universal 应用程序部署到 Node.js 生产服务器?

    我有一个带有 Universal 的 Angular 8 应用程序 我想将其部署到共享 Web 主机生产服务器 我提前与网络主机核实过 他们告诉我可以在他们的共享网络托管上托管 Angular 通用网络应用程序 但是 无论我做什么 我都无法
  • 如何显示接下来的三个图像单击加载更多按钮

    我需要一个加载更多按钮来显示图像 页面加载时 我显示 3 个图像 单击 加载更多 按钮后 接下来的 3 个图像将显示在屏幕上 我尝试了下面的代码 但它不起作用 你能帮我解决这个问题吗 function item slice 0 2 show
  • Firefox Addon 中的 JQuery 导致多个警告

    我在 Firefox 插件中使用 jquery 但我不断收到大量警告消息 如下所示 anonymous function does not always return a value System JS WARNING resource g
  • Chrome --app 相当于 Firefox\IE

    我有一个网络应用程序 客户要求单击不同按钮时更改浏览器窗口大小 我发现在那link https stackoverflow com questions 13436855 launch google chrome from the comma
  • ES6 模块范围

    我有代码 lib js var a a export var b b main js console log a a variable is not available in a global scope import b from lib
  • 如何让 Typescript 获取声明文件?

    My file src auth ManagementAPI ts使用 Auth0 我需要使用自己的声明文件并创建src types auth0 d ts 然而 当我跑步时ts node 我收到此错误 TSError Unable to c
  • 如何从 html 页面 [javascript] 调用 Web 服务方法而不刷新页面

    我有一个webservice这将返回一个值 我的要求是 我需要调用它webservice从一个index html页面 该页面有一个 html 提交按钮 在该按钮上单击我正在呼叫JavaScript 从那里我想调用网络方法 我怎样才能做到这
  • 如何导入 nano (couchdb) - typescript

    我在节点应用程序中导入和使用 nano 时遇到问题 js 方式 来自文档 是 var nano require nano http localhost 5984 我该如何用打字稿做到这一点 I tried import as Nano fr
  • 如何从 CSS 选择器中提取类名?

    故事 我目前正在构建一个 ESLint 规则 以警告在 CSS 选择器定位器中使用引导布局导向和角度技术类 目前我在字符串方法中使用简单的子字符串 for var i 0 i lt prohibitedClasses length i if
  • 为什么 call 比 apply 快那么多?

    我想知道是否有人知道why call比apply 在 Chrome 中 速度大约快 4 倍 在 Firefox 中快 30 倍 我什至可以制作自定义原型 apply2 在大多数情况下 运行速度是apply 这个想法取自角度 Function
  • 使用 rxjs 将数据添加到 http 响应

    我有一个包含司机 ID 的旅行实体 我可以使用 RESTFull 端点获取获取行程 例如 trips 2 example response id 2 driver id 123 我可以使用端点获取驱动程序详细信息 例如 drivers 12
  • 如何在 TypeScript 中使用 navigation.replace ?

    我试图在我的代码中使用它 const navigation useNavigation navigation replace AllFriends 但我不断收到错误消息 Property replace does not exist on
  • Three.js点击单个粒子

    In this example http jsfiddle net agqq96bq 2 您可以看到 2 个可点击的粒子 但它们都受到点击的影响 另外 我只想检测粒子上的点击 而不将它们过滤出场景 像这儿 if intersects len
  • Vue - 调度完成后调用 store getter?

    我正在使用 Laravel 5 7 Vue2 Vuex 我在调度调用完成后让 Vue 返回存储值时遇到一些困难 我的申请流程如下 我单击一个提交按钮 该按钮调用组件上的 validate Validate 分派到我的 addLease 操作
  • 如何让 webpack 和 iis express 协同工作?

    I have Angular 2 和 Webpack 2 入门 https github com qdouble angular webpack2 starter它通过 webpack dev server 在节点上运行 我如何使用 web

随机推荐