简体   繁体   English

如何在C#等待调用中使用Rx从Web检索JSON数据

[英]How can I use Rx with C# await calls to retrieve JSON data from web

I have a method that calls an API with HttpClient and build a list of Customers as IEnumberable<Customer> . 我有一种方法,可以使用HttpClient调用API并以IEnumberable<Customer>形式IEnumberable<Customer> The way this API works is that it will return only 100 customers at a time, and will provide another link in the JSON content to fetch again the next 100. 该API的工作方式是一次仅返回100个客户,并在JSON内容中提供另一个链接以再次获取下一个100个客户。

How can I structure this code to iteratively fetch the records until all are fetched and build a large IEnumerable<Customer> and return from this method. 如何构造此代码以迭代方式获取记录,直到获取所有记录,并构建一个大的IEnumerable<Customer>并从此方法返回。 I'm looking for the solution with Rx. 我正在寻找Rx解决方案。

Task<IEnumerable<Customer>> GetCustomers(string url)
{
  HttpClient client = new HttpClient();
  HttpResponseMessage response = await client.GetAsync(url);
  response.EnsureSuccessStatusCode();
  string responseBody = await response.Content.ReadAsStringAsync();

  // TODO: Deserialize responseBody and build a new IEnumerable<Customer>
}

Json:

{
    nextRecords: '\customers\123'
    customers: [
        {
            name: 'John Doe'
        },
        {
            name: 'Mary Doe'
        }
        ]
}

I've changed the signature from Task<IEnumerable<Customer>> to IObservable<Customer> to make it more Rx-like. 我已将签名从Task<IEnumerable<Customer>>更改为IObservable<Customer> ,以使其更像Rx。

You need to define the Func<JObject, IObservable<Customer>> createCustomers function. 您需要定义Func<JObject, IObservable<Customer>> createCustomers函数。

Try having a go at this: 尝试一下:

IObservable<Customer> GetCustomers(string url)
{
    Func<JObject, IObservable<Customer>> createCustomers = jo => { ... };
    return Observable.Create<Customer>(o =>
    {
        var final_url = url + "\\customers";
        return
            Observable
                .While(
                    () => final_url != url,
                    Observable
                        .Using(
                            () => new HttpClient(),
                            client =>
                                from x in Observable.FromAsync(() => client.GetAsync(final_url))
                                from y in Observable.Start(() =>
                                {
                                    x.EnsureSuccessStatusCode();
                                    return x;
                                })
                                from z in Observable.FromAsync(() => y.Content.ReadAsStringAsync())
                                from w in Observable.Start(() =>
                                {
                                    var j = JObject.Parse(z);
                                    final_url = url + j.Property("nextRecords").Value;
                                    return createCustomers(j);
                                })
                                from v in w
                                select v))
                .Subscribe(o);
    });
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM