Typescript不会加载在函数外声明的数组。请建议

时间:2017-12-21 00:03:34

标签: typescript

发出http请求并解释响应。响应包含未在函数中加载的对象和数组。

Notes:- making http request.

public getRequest(): void {
    let bdoNamesArray: BdoName[];
    bdoNamesArray = [];

    this.http.get<BdoName[]>(this.bdoNamesUrl, {observe: 'response', responseType: 'json'})
      .subscribe((data: HttpResponse<BdoName[]>) => {
            let vjyArray: BdoName[];
            vjyArray = [];
            for (let i = 0; i < data.body.length; i++) {
                  const obj = new BdoName();
                  obj.emplid = data.body[i].emplid;
                  obj.name = data.body[i].name;
                  vjyArray.push(obj); }
          console.log(vjyArray); // Array loaded from http-response
          bdoNamesArray.concat(vjyArray); // not loaded
          },
        error => {
          console.log('error on sub');
        },
        () => {
          console.log('sub completed');
        }
    );
    console.log(bdoNamesArray); // Emtpy array !!
}

1 个答案:

答案 0 :(得分:1)

当您在最后执行console.log时,该数组为空,因为该数组在执行时在技术上是空的。这是因为您操作数组的代码将来某个时间运行,而不是在订阅GET请求后直接运行。

例如;代码的执行是这样的:

  1. let bdoNamesArray: BdoName[]; bdoNamesArray = [];
  2. 触发GET数据的事件 this.http.get<BdoName[]>(this.bdoNamesUrl, {observe: 'response', responseType: 'json'})

  3. 您订阅时,只要此事件返回我的数据,就会订阅此事件

     let vjyArray: BdoName[];
        vjyArray = [];
        for (let i = 0; i < data.body.length; i++) {
                const obj = new BdoName();
                obj.emplid = data.body[i].emplid;
                obj.name = data.body[i].name;
                vjyArray.push(obj); 
    }
    console.log(vjyArray); 
    // ... 
    
  4. 它会继续并执行console.log(bdoNamesArray);,您会注意到它是一个空数组。

    将来的某个时间: 您的bdoNamesArray由您在步骤3中输入的逻辑填充

  5. 因此,您的代码正在异步运行 ,因此您需要将您的逻辑发展为您在异步调用的回调中所执行的任何操作。

    解决此问题的一种方法是返回observable本身,让调用者决定结果的逻辑。

    示例(假设this.http.get()返回一个observable):

    public getRequest(): Observable<any> {
        let bdoNamesArray: BdoName[];
        bdoNamesArray = [];
    
        let result = this.http.get<BdoName[]>(this.bdoNamesUrl, {observe: 'response', responseType: 'json'});
    
        return result;
    }
    

    另一种方法是你有另一个回调函数:

    public getRequest(): void {
        let bdoNamesArray: BdoName[];
        bdoNamesArray = [];
    
        this.http.get<BdoName[]>(this.bdoNamesUrl, {observe: 'response', responseType: 'json'})
          .subscribe((data: HttpResponse<BdoName[]>) => {
                doStuff(data);
              },
              //...
    }