Angular (v5) 服务正在 APP_INITIALIZER 承诺解析之前构建

2024-03-24

我期待 Angular 等到我的loadConfig()函数在构建其他服务之前解析,但事实并非如此。

应用程序模块.ts

export function initializeConfig(config: AppConfig){
    return () => config.loadConfig();
}

@NgModule({
     declarations: [...]
     providers: [
          AppConfig,
         { provide: APP_INITIALIZER, useFactory: initializeConfig, deps: [AppConfig], multi: true }
     ] })
export class AppModule {

}

应用程序配置.ts

@Injectable()
export class AppConfig {

    config: any;

    constructor(
        private injector: Injector
    ){
    }

    public loadConfig() {
        const http = this.injector.get(HttpClient);

        return new Promise((resolve, reject) => {
            http.get('http://mycoolapp.com/env')
                .map((res) => res )
                .catch((err) => {
                    console.log("ERROR getting config data", err );
                    resolve(true);
                    return Observable.throw(err || 'Server error while getting environment');
                })
                .subscribe( (configData) => {
                    console.log("configData: ", configData);
                    this.config = configData;
                    resolve(true);
                });
        });
    }
}

其他一些服务.ts

@Injectable()
export class SomeOtherService {

    constructor(
        private appConfig: AppConfig
    ) {
         console.log("This is getting called before appConfig's loadConfig method is resolved!");
    }
 }

的构造函数SomeOtherService在从服务器接收数据之前被调用。这是一个问题,因为这样的字段SomeOtherService没有设置为正确的值。

我如何确保SomeOtherService的构造函数仅在之后被调用loadConfig的请求解决了吗?


我也遇到了类似的问题,为我解决这个问题是使用 Observable 方法和运算符来完成所有操作。然后最后只需使用toPromise的方法Observable返回一个Promise。这也更简单,因为您不需要自己创建承诺。

The AppConfig服务将看起来像这样:

import { Injectable, Injector } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import { tap } from 'rxjs/operators/tap';

@Injectable()
export class AppConfig {

    config: any = null;

    constructor(
        private injector: Injector
    ){
    }

    public loadConfig() {
        const http = this.injector.get(HttpClient);

        return http.get('https://jsonplaceholder.typicode.com/posts/1').pipe(
          tap((returnedConfig) => this.config = returnedConfig)
        ).toPromise();
        //return from([1]).toPromise();
    }
}

我正在使用新的可管道操作符 https://github.com/ReactiveX/rxjs/blob/master/doc/pipeable-operators.md在 rxjs 中,这是 Google 为 Angular 5 推荐的。tap运算符相当于旧的do操作员。

我还在 stackblitz.com 上创建了一个工作示例,以便您可以看到它工作。示例链接 https://stackblitz.com/edit/angular-5nhqbp?file=app%2Fapp-config.ts

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

Angular (v5) 服务正在 APP_INITIALIZER 承诺解析之前构建 的相关文章

随机推荐

  • 如何存储大量数据?

    我必须 在状态机上 制作 RSA 签名C在 32 位板上 我的内存有限 所以我无法将小数存储在向量或类似的东西中 最好的事情是如果我可以存储位并且可以轻松访问它们 什么存储方法最好 我做了这个 if CPU TYPE CPU TYPE 32
  • 通过 PHP 的 JS 解包器 - 函数(p,a,c,k,e,r)

    我在互联网上搜索但到目前为止没有找到解决方案 我必须抓取用以下内容压缩的页面 具有视频流 的内容Dean Edwards 封隔器工具 http dean edwards name packer 实时 因此 我只需要通过 PHP 来解码压缩的
  • 通过 Java 执行 ADS 相关的 Powershell 命令不起作用,使用 2 种不同的方式时会出现 2 种不同的错误

    我一直在尝试通过 java 在 powershell 会话中执行一组命令 但还没有成功 我的目标是在 AD 中搜索域为 domain com 的计算机对象 我从一个命令开始 不幸的是 以下命令在我的 powershell 提示符下成功运行
  • 图像不显示在 jar 中但显示在编译器中?

    我知道 我知道 这个问题以前有人问过 但我看过的每个资源都使用 IconImages 而我只有普通图像 有不同的解决方案吗 请帮助 因为我已经坚持研究并试图解决这个问题好几天了 但没有任何进展 Image Floor Toolkit get
  • 何时使用块

    我喜欢红宝石块 它们背后的想法非常非常简洁和方便 我刚刚回顾了过去一周左右的代码 基本上是我写过的每一个 ruby 函数 而且我注意到它们中没有一个返回值 我总是使用块来传回数据 而不是返回值 我什至发现自己正在考虑编写一个小状态类 这将允
  • 如何在ubuntu 15.04中安装poppler?

    Poppler 是一个基于 xpdf 3 0 代码库的 PDF 渲染库 我已经从官方网站下载了 tar xz 文件http poppler freedesktop org http poppler freedesktop org 但我不知道
  • 从另一个范围中的值定义一个范围

    我有一个 Excel 文件 其中包含已完成或未完成的任务 并在列中用 是 或 否 表示 最终 我对不同列中的数据感兴趣 但我想设置代码 以便它忽略任务已完成的那些行 到目前为止 我已经定义了包含是 否的列范围 但我不知道在此范围上运行哪个命
  • C# 中的通用 Func<> 类型

    我正在用 C 编写一个小型 Lisp 解释器 它基本上已经可以工作了 目前我正在使用一个接口来表示函数 public interface LispFunction object Apply ArrayList parameters 该接口由
  • 如何在 pygame 中有效地遮盖表面

    我按照建议掩盖 pygame 中的表面nkorth https stackoverflow com users 685933 nkorth回答问题有没有办法只在掩码中进行位块传输或更新 https stackoverflow com a 1
  • 我什么时候应该使用 stdClass,什么时候应该在 php oo 代码中使用数组?

    在工作中的大规模重构期间 我希望引入 stdClass 作为从函数返回数据的一种方式 并且我正在尝试找到非主观论据来支持我的决定 在什么情况下最好使用其中一种而不是另一种 使用 stdClass 而不是数组有什么好处 有人会说函数必须尽可能
  • 降低滚动视图中平滑滚动的速度[重复]

    这个问题在这里已经有答案了 我有一个滚动视图 我执行 smooth scroll using smoothScrollBy 一切正常 但我想更改平滑滚动的持续时间 平滑滚动发生得非常快 用户不明白发生了什么 请帮助我降低平滑滚动速度 简单的
  • 通过蓝牙打印机 Android 打印 Pdf 文件

    在我的项目中需要通过蓝牙打印机打印Pdf文件 我写了一个代码通过pdf打印 它对于文本来说很好 但我想在蓝牙打印机上打印PDF文件 我的打印文本的java代码 Override public void onCreate Bundle sav
  • 如果类包含基类的成员,编译器可以利用空基优化吗?

    Consider struct base struct child base 众所周知sizeof child 可以通过应用 1空碱基优化 然而现在 考虑一下 struct base struct child base base b 编译器
  • 在jqgrid的列中添加图像

    我想在 jqgrid 的第一列中显示一个小图像 以显示从数据库获取的所有数据 jquery tableName jqgrid colNames colModel width 25 name someValue index somevalue
  • 访问数组数组内数组的行?

    说我有 H array a array b array c a 1 2 3 4 5 6 11 22 33 44 55 66 row 1 of H 0 111 222 333 444 555 666 b 7 8 9 0 1 2 77 88 9
  • 限制 JTextField 中输入的长度不起作用

    我试图限制用户可以在文本字段中输入的字符的最大长度 但它似乎不起作用 这是代码 text2 new JTextField Enter text here 8 我做错了什么吗 如何才能使限制正常工作 您当前的代码没有设置最大长度 而是定义可见
  • BroadcastReceiver 与 WakefulBroadcastReceiver

    有人可以解释一下两者之间的确切区别是什么BroadcastReceiver https developer android com reference android content BroadcastReceiver html and W
  • WPF - 如何在任一时间仅扩展一个扩展器

    我有一个带有一组扩展器的 StackPanel 如何设置它以便在任何时候都只扩展扩展器 Cheers AW 我真的不想这样做 因为它需要将代码 C 放在窗口文件后面的类中 我试图通过使用 ViewModels 等来完全避免这种情况 理想情况
  • 如何在 Bootstrap 4 中均匀分布导航栏元素

    为网站构建引导程序导航 我在弄清楚如何最好地间隔导航栏上的导航链接元素时遇到了一些麻烦 并继续在移动设备上看起来不错 我的导航栏代码是
  • Angular (v5) 服务正在 APP_INITIALIZER 承诺解析之前构建

    我期待 Angular 等到我的loadConfig 函数在构建其他服务之前解析 但事实并非如此 应用程序模块 ts export function initializeConfig config AppConfig return gt c