首页 > 解决方案 > 关于 Ember 中异步的一些问题

问题描述

我在一段时间内使用 emberjs,现在我想完善我对 ember 本质的理解。

问题 1.model()路由的钩子是编写异步代码(获取所有需要的数据)的最佳位置, 我说得对吗?我是否应该尝试将所有网络请求(或至少大部分)放在路由模型中?

问题 2. 组件钩子具有同步性。这是否意味着在钩子中编写异步代码是一个错误的决定?

比如说,我有一个异步init()钩子来计算一些数据,并didRender()在我希望使用这些数据的地方钩子。当 ember 调用init()时,它返回一个 Promise,因此它从堆栈移动到一个特殊的队列,并且 ember 不会等到事件循环将该代码返回到堆栈。所以 ember 会运行下一个钩子,而当didRender()被执行时,init()钩子可能没有完成,预期的数据可能不存在。那正确吗?

问题 3. 服务挂钩也应该是同步的。因为当服务被注入到组件中并被使用时,ember 也不会等到异步钩子完成。

比如说,我有一个带有products属性的购物车服务。产品 ID 存储在本地存储中,我想从服务器获取这些产品以将它们设置为products属性。

import Service from '@ember/service';
import { A } from '@ember/array';
import { inject as service } from '@ember/service';

export default Service.extend({
    store: service(),

    init(...args) {
        this._super(args);
        this.set('products', A());
    },

    async loadProducts() {
        const cartProducts = A();
        const savedCartProducts = localStorage.getItem('cartProducts');
        if (savedCartProducts) {
            const parsedSavedCartProducts = JSON.parse(savedCartProducts);
            const ids = Object.keys(parsedSavedCartProducts);
            if (ids.length > 0) {
                const products = await this.store.query('product', {id: Object.keys(parsedSavedCartProducts)});
                products.forEach(p => {
                    p.set('cartQuantity', Number(parsedSavedCartProducts[p.id].qty));
                    cartProducts.pushObject(p);
                });
            }
        }
        this.products.pushObjects(cartProducts);
    },
  ...
});

例如,如果我loadProducts()从服务中调用,init()我将无法使用this.cart.productsin controllers/application.js。因为服务已经准备好了,但是异步init()还在执行。那么,我应该在routes/application.js model()挂钩中调用它吗?

问题 4. 如果有一些通用组件不引用任何路由,但该组件需要来自服务器的一些数据,我应该在哪里发出异步请求?还是计算属性和观察者是唯一的解决方案?

非常感谢。

标签: ember.js

解决方案


好问题在这里,你在正确的轨道上!

问题 1:是的,一般的经验法则是,在您熟悉事物之前,在路由钩子( 和 )中进行异步工作beforeModel可以modelafterModel容易地思考正在发生的事情。最终,您可能希望开始调整默认值以适应您的自定义 UI 需求,但从这条规则开始是最简单的

问题 2-4:你在这里问了几个关于异步代码的问题,所以在这里更广泛地回答。

首先,服务可以异步或不异步,但除非您从钩子(如路由钩子)调用这些方法,否则您负责处理异步结果。例如,Ember 数据存储是一个异步返回数据的服务

但是,如果您遇到确实需要在组件中执行异步的情况,推荐的帮助解决此问题的插件是 Ember Concurrency:http ://ember-concurrency.com/docs/introduction/

Ember Concurrency 有助于解决您尚未遇到的许多异步错误和边缘情况,但如果您开始在组件中编写异步代码,它们将会解决。因此,我强烈建议您了解更多有关它的信息。

祝你好运!


推荐阅读