离子2中的重复http请求与异步管道

时间:2017-09-12 07:32:59

标签: angular typescript ionic2 rxjs ionic3

我是离子2的新手。我正在使用离子v3.6.1。

请注意,http请求是fire x次,其中x是使用异步管道发布的请求绑定。 因此,在这种情况下,http请求被触发3次。

请告知这是最佳做法。

提供者:

@POST
@Path("/aa")
@Consumes(MediaType.APPLICATION_JSON)
public Response polaki(User user, @HeaderParam("Authorization") String authString, @HeaderParam("API_KEY") String apikey) throws Exception {
    if (authString.equals(UserSetting.Authorization) & apikey.equals(UserSetting.API_KEY)) {
        tx = session.getTransaction();

        tx.begin();
        Query query = session.createQuery("from Service where  service=:service");
        query.setParameter("service", user.getService());
        tx.commit();
        List ls= query.list(); // Eror

        return Response.status(200).entity("{\"message\":\"Service Eror\"}").build();
    } else {
        return Response.status(200).entity("{\"message\":\"Service Eror\"}").build();
    }
}

ts文件:

  getPostById(id: number) {
    return this.http.get(`${this.rootUrl}/${this.posts}/${id}`).map(res => res.json()).take(1);
  }

HTML

post: Observable<Post>;
ionViewDidLoad() {
    this.postId = this.navParams.get('postId');
    console.log(this.postId);
    this.post = this.data.getPostById(this.postId);
  }

2 个答案:

答案 0 :(得分:2)

share()运算符

每次订阅感冒Observable时,都会执行。避免这种行为的一种方法是使其变热。您可以使用.share()operator(这是.publish().refCount()的简写来完成此操作,有关这些运算符的更多信息,请参阅更多信息):

  

返回一个新的Observable,它可以多播(共享)原始的Observable。只要至少有一个订阅者,此Observable将被订阅并发送数据。当所有订阅者都取消订阅时,它将取消订阅源Observable。因为Observable是多播,所以它使流变热。这是.publish().refCount()的别名。

ionViewDidLoad() {
    this.postId = this.navParams.get('postId');
    console.log(this.postId);
    this.post = this.data.getPostById(this.postId).share();
  }

有条件的怪癖

如果您在模板中第一次使用Observable,然后在有条件附加的元素(*ngIf)内再次使用它,您可能会遇到一些麻烦,因为可观察到的已经运行,不会发出新数据。

例如:

模板:

{{ (post | async)?.id }}
<div *ngIf="post|async">
    {{ (post | async)?.title}}
    {{ (post | async)?.content}}
</div>

ts:

post: Observable<Post>;
ionViewDidLoad() {
    setTimeout(()=>this.show=true, 5000);
    this.postId = this.navParams.get('postId');
    console.log(this.postId);
    this.post = this.data.getPostById(this.postId).share();
  }

此处share运算符(单独)是不够的,因为发布了post,因此ngIf条件变为true,但子异步管道订阅已经发出其值的Observable。基本上它呈现这样的东西:

myPostID
<div></div>

有两种方法可以解决这种情况:

  1. .publishReplay(n):此运算符将重放Observable发出的最后n项。我们将此运算符与refCount()结合起来,它将跟踪订阅者的数量,并且如果没有更多订阅者,将重置冷可观察量。

    this.post = this.data.getPostById(this.postId).publishReplay(1).refCount();
    
  2. 使用*ngIf="post |async as myPost"这个语法是在角度4(或者4.1,我无法记住)中引入的,它允许您将管道的结果存储在局部变量{{1}中}。 explainations here。因此,您可以将myPost部分保留在ts代码中,最终得到这样的模板:

    .share()
  3. 关于{{ (post | async)?.id }} <div *ngIf="post|async as myPost"> {{ myPost.title}} {{ myPost.content}} </div> publish()的两个字:

    refCount()将常规publish()转换为Observable。这种Observable在调用ConnectableObservable方法后立即开始发送数据(它使得可观察的热点)。

    来自the docs

      

    connect()

         

    返回一个可观察序列,该序列是在可连接的可观察序列上调用选择器的结果,该序列共享对基础序列的单个预订。

    Rx.Observable.prototype.publish([selector])refCount()上可用的方法,其作用是在第一次订阅时调用ConnectableObservable方法。如果所有订阅者都取消订阅,然后另一个订阅者要求订阅,则会再次调用它。

    来自the docs

      

    connect()

         

    只要对可观察序列至少有一个订阅,就返回一个与源保持连接的可观察序列。

答案 1 :(得分:1)

您可以在此处遵循以下模式:

.TS

post: Post;
ionViewDidLoad() {
    this.postId = this.navParams.get('postId');
    console.log(this.postId);
    this.data.getPostById(this.postId).subscribe(data => {
        this.post= data;
    });

  }

模板就像:

html的

{{ post?.id }}
{{ post?.title}}
{{ post?.content}}