【问题标题】:Angular 2: How to call a function after get a response from subscribe http.postAngular 2:从订阅 http.post 获得响应后如何调用函数
【发布时间】:2017-07-03 11:46:25
【问题描述】:

从http post请求中获取数据后需要调用一个方法

服务:request.service.TS

get_categories(number){
 this.http.post( url, body, {headers: headers, withCredentials:true})
    .subscribe( 
      response => {
        this.total = response.json();

      }, error => {
    }
  ); 

}

组件:categories.TS

search_categories() {

this.get_categories(1);
//I need to call a Method here after get the data from response.json() !! e.g.: send_catagories();
}

仅当我更改为:

服务:request.service.TS

get_categories(number){
 this.http.post( url, body, {headers: headers, withCredentials:true})
    .subscribe( 
      response => {
        this.total = response.json();
        this.send_catagories(); //here works fine

      }, error => {
    }
  ); 

}

但是我需要像这样在调用this.get_categories(1);之后调用组件内部的方法send_catagories()

组件:categories.TS

search_categories() {

this.get_categories(1);
this.send_catagories(response);
}

我做错了什么?

【问题讨论】:

  • send_catagories() 是否也在使用 observable?如果是,您需要使用 .mergeMap() 运算符将 get_categories() 中的 observable 链接到 send_categories() 中的那个。如果您需要语法方面的帮助,请告诉我。
  • send_catagories() 没有使用 observable,请告诉我语法:return this.http.post( url, body, {headers: headers, withCredentials:true}) .subscribe( response => { this.total_page = response.json();返回 this.total_page; }, .share() ); } 然后 this.get_category(1).subscribe(response=> { this.callfunc(); });
  • 知道了。我已经用正确的语法发布了一个答案。

标签: javascript angular typescript promise subscribe


【解决方案1】:

您可以将回调函数添加到您的 get_category(...) 参数列表中。

例如:

 get_categories(number, callback){
 this.http.post( url, body, {headers: headers, withCredentials:true})
    .subscribe( 
      response => {
        this.total = response.json();
        callback(); 

      }, error => {
    }
  ); 

}

然后你可以像这样调用 get_category(...) :

this.get_category(1, name_of_function);

【讨论】:

  • 谢谢,我会努力的。但我的想法是使用更专业的东西来捕捉响应。例如:get_category(1).then 或 observable 但我不知道该怎么做
  • 使用回调函数没有什么不专业的,但适合自己
  • 在我看来,在使用 observables 时将回调传递给服务并不是一个好的模式。正如 Louis 所暗示的,它使额外的逻辑和错误处理变得丑陋。
  • @RobM 我只是想说你是对的。在重写同事应用程序时,我去回调地狱又回来了,现在我看到了错误!
【解决方案2】:
get_categories(number){
 return this.http.post( url, body, {headers: headers, withCredentials:true})
      .map(t=>  {
          this.total = t.json();
          return total;
      }).share();
  );     
}

然后

this.get_category(1).subscribe(t=> {
      this.callfunc();
});

【讨论】:

  • 是的!这就是我想要的,如何在没有“.map”的情况下保留旧语法?例如:return this.http.post( url, body, {headers: headers, withCredentials :true}) .subscribe( response => { this.total = response.json(); return total; }).share();
  • (173,69):错误 TS2339:“订阅”类型上不存在属性“订阅”。
  • 为什么要原始语法? FRP 是关于组合流以创建一个可以订阅的有意义的 observable。
  • @pixelbits 我收到一条错误消息,指出.share does not exist on type Observable<any> 并且return total 不应该是return this.total?只是想弄清楚这段代码,因为我正在努力解决类似的问题。
【解决方案3】:

更新您的get_categories() 方法以返回总数(包装在可观察对象中):

// Note that .subscribe() is gone and I've added a return.
get_categories(number) {
  return this.http.post( url, body, {headers: headers, withCredentials:true})
    .map(response => response.json());
}

search_categories() 中,您可以订阅get_categories() 返回的可观察对象(或者您可以通过链接更多的RxJS 运算符来继续对其进行转换):

// send_categories() is now called after get_categories().
search_categories() {
  this.get_categories(1)
    // The .subscribe() method accepts 3 callbacks
    .subscribe(
      // The 1st callback handles the data emitted by the observable.
      // In your case, it's the JSON data extracted from the response.
      // That's where you'll find your total property.
      (jsonData) => {
        this.send_categories(jsonData.total);
      },
      // The 2nd callback handles errors.
      (err) => console.error(err),
      // The 3rd callback handles the "complete" event.
      () => console.log("observable complete")
    );
}

请注意,最后您只订阅一次

就像我在 cmets 中所说的,任何 observable 的 .subscribe() 方法都接受 3 个这样的回调:

obs.subscribe(
  nextCallback,
  errorCallback,
  completeCallback
);

它们必须按此顺序传递。你不必通过所有三个。很多时候只实现了nextCallback

obs.subscribe(nextCallback);

【讨论】:

  • 谢谢,谢谢,谢谢!它工作完美!只有两个问题,1)在 this.send_categories(total){ this.myNewTotal= total } 里面我如何从“total”参数中提取数据(responde.json)? 2)我在语法中添加了“错误”: .map(response => response.json()), error => { } );如果我只需要在错误情况下调用 this.send_categories(total) ,我如何订阅错误?
  • 嗯。根据您之前的代码,我认为response.json() WAS 是总数。我的意思是,我将变量命名为total,但它包含response.json() 中的任何内容;你可以随意命名这个变量。我更新了我的答案以更好地反映这一点,并向您展示如何处理错误。
  • 我可能错过了订阅中第三个参数的要点,但我想知道您是否可以调用一个方法来完成回调?
  • 通常这两个回调是同义词。以 HTTP 请求为例。当服务器返回数据时,nextCallback 被调用,然后紧跟在completeCallback 之后。但在不同的情况下(例如聊天系统),nextCallback 可以被多次调用(例如,对于每个聊天通知),completeCallback 永远不会被调用。
  • 有史以来最好的解释。
【解决方案4】:

您可以将 lambda 表达式编码为 subscribe 方法的第三个参数(完成时)。这里我将departmentModel变量重新设置为默认值。

saveData(data:DepartmentModel){
  return this.ds.sendDepartmentOnSubmit(data).
  subscribe(response=>this.status=response,
   ()=>{},
   ()=>this.departmentModel={DepartmentId:0});
}

【讨论】:

    【解决方案5】:

    您也可以使用新的Subject 来做到这一点:

    打字稿:

    let subject = new Subject();
    
    get_categories(...) {
       this.http.post(...).subscribe( 
          (response) => {
             this.total = response.json();
             subject.next();
          }
       ); 
    
       return subject; // can be subscribed as well 
    }
    
    get_categories(...).subscribe(
       (response) => {
         // ...
       }
    );
    

    【讨论】:

    • @Pratik 你这是什么意思?
    • 表示第一条语句 let subject = new Subject();由于没有主题类而给出错误。
    • @Pratik 你需要 rxjs
    • 继续提及 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-12-12
    • 2017-06-25
    • 2017-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多