【问题标题】:Angular 8 httpclient code running out of orderAngular 8 httpclient 代码乱序运行
【发布时间】:2019-12-10 20:36:28
【问题描述】:

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

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

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

【问题讨论】:

    标签: angular angular-httpclient


    【解决方案1】:

    上一个答案是否意味着通过在组件级别返回一个可观察对象和订阅来解决问题,并在数据可用时将任何下一步移动到订阅主体,async/await 可以做相同的结果,但没有太多的变化

    网络服务

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

      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 ?

    【讨论】:

    • 把答案改成了这个,再次感谢!这个更符合我的目标,但每个答案都有很好的经验教训,谢谢
    【解决方案2】:

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

    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 ?

    【讨论】:

    • 谢谢,这确实解决了我的问题,我完全忘记了异步方法。但是难道不能在WebService阶段获取所有信息吗?像运行 http.get 并将结果作为字符串返回?您是否必须在组件级别运行 subscribe 方法才能使任何 http 调用正常工作?
    • 是的,可以使用回调但不推荐,我将使用promise写另一种方式?
    • @5tar-Kaster 用异步等待检查另一个答案
    猜你喜欢
    • 1970-01-01
    • 2015-02-26
    • 1970-01-01
    • 2019-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-04
    相关资源
    最近更新 更多