Angular 8 httpclient 代码 运行 乱序

Angular 8 httpclient code running out of order

我正在尝试使用 Angulars HttpClientModule 从资产文件夹中的文件加载内容。然而,当 WebService.webCall 方法是 运行 时,方法 运行 中的所有内容看起来都以错误的顺序排列。我在这里创建了一个 stackblitz 代码示例来演示我遇到的问题,https://stackblitz.com/edit/angular-avuhul

代码 100% 正常工作,除了返回空字符串的方法和稍后加载文件中的数据,但它总是在方法已经返回之后,对我来说太晚了对文件的内容做任何逻辑。

我不确定是什么原因造成的,在我查看 Whosebug 的任何地方,我都看到对旧版本 Angular 的引用。我想这就是为什么这些解决方案无法解决我的问题的原因。

http.get 调用是异步调用,在您刚刚订阅时 webGet 方法将 return 结果,因此要解决此问题,您需要将服务 webGet 更新为return observable 然后你可以在组件上订阅这将是比在服务级别处理订阅更好的方法。

webGet(url: string, prefix: string) {
    //log the start of the web call
    this.log(prefix + "(001) run webGet [" + url + "]");

    //create the headers
    const headers = new HttpHeaders().set(
      "Content-Type", "text/plain; charset=utf-8"
    );

    //create the result
    var result: string = "";

    return this.http.get(url, { headers, responseType: "text" })

  }

demo

之前的答案是否意味着通过 return 在组件级别的可观察和订阅来解决问题,并在数据可用时将任何下一步移动到订阅主体,async/await 可以做到结果相同,但变化不大

网络服务

只需将 observable 转换为 promise 并更改 return 类型

  getConfigFile(url: string): Promise<string> {
    return this.webGet(url, "[1] - ");
  }
  getContentsFile(url: string): Promise<string> {
    return this.webGet(url, "[2] - ");
  }

 webGet(url: string, prefix: string): Promise<string> {
    //log the start of the web call
    this.log(prefix + "(001) run webGet [" + url + "]");

    //create the headers
    const headers = new HttpHeaders().set(
      "Content-Type", "text/plain; charset=utf-8"
    );

    //create the result
    var result: string = "";

    //  run the http Get method
    return  this.http.get(url, { headers, responseType: "text" }).toPromise();
  }

组件

只需在 reloadConfig 和 reloadFile 前加上 async 关键字,并在 getContentsFile 和 getConfigFile 前加上 await 关键字

//  web call method
  async reloadConfig() {
    console.clear();
    console.log("===================");

    //  testing with a config json file
    this.config = await this._web.getConfigFile("/assets/config.json");
    this.log("loaded config data: " + this.config);

    //check if the file loaded
    if (this.config.length > 0){
      //apply some logic to the config file
      this.modified = "config file contains [" + this.config.length + "] chars";
    } else {
      this.log("config data is empty");
    }
  }

  // web call method
  async reloadFile() {
    console.clear();
    console.log("===================");

    //  testing with a blank file containing text
    this.contents = await this._web.getContentsFile("/assets/filewithcontents");
    this.log("loaded contents data: " + this.config);

    //check if the file loaded
    if (this.contents.length > 0){
      //apply some logic to the config file
      this.modified = "contents file contains [" + this.contents.length + "] chars";
    } else {
      this.log("contents data is empty");
    }
  }

demo