加入多个可以在一个可观察到的HTTP调用中有条件地发生

发布于 2025-02-03 04:53:20 字数 1529 浏览 4 评论 0原文

为了示例,可以说我有一个称为客户端的实体:

interface Client {
   id: number
   name: string
   address: Address[]
}

interface Address {
   id: number
   street: string
}

在这种情况下,我无法在同一调用中更新客户端的name 地址。

相反,我需要:

  • 检查要创建的地址,然后一一创建(并存储以后要使用的值)
  • 检查要更新的地址,然后一一更新(并存储稍后使用的值)
  • ,最后DO DO另一个呼吁将客户的名字命名。

因此,我想做的是加入这个多个可以在一个可观察到的HTTP调用中。

这就是我到目前为止的:

updateClientAndClientAddresses(): Observable<Client> {       

   return of({}).pipe(
     ******* Conditionally make all the create addresses calls *******
     ******* Conditionally make all the update addresses calls *******
     *******   Then make the update name call *******

     switchMap(([updateNameResponse: Client, responseOfAllAddressesToBeCreated: Address, responseOfAllAddressesToUpdated: Address]) => {
    // Ideally here I will have the results of all the calls made so far.

    // Merge everything manually here
    return {
      ...updateClientCallResponse,
      addresses: [
        ...responseOfAllAddressesToBeCreated,
        ...responseOfAllAddressesToUpdated
      ]};
  }),
)
}

只是要加强: 在拨打电话以更新名称之前,我需要检查是否:

  • adversioneStobecReated.length.length如果是的,我需要为此数组的每个lenght进行一个特定的调用,等待响应并将结果存储为在后来使用。

然后,我需要检查以下内容:

  • adverseEstupded.length.length如果是的,我需要执行另一个特定的调用该数组的每个lenght,并等待响应并存储结果以要使用后者。

  • 最后,我将打电话以更新客户端的名称,获取结果,然后与我有条件做出的所有响应合并。

For the sake of the example lets say I have a entity called client:

interface Client {
   id: number
   name: string
   address: Address[]
}

interface Address {
   id: number
   street: string
}

In this case I cannot update the name of client and his addresses in the same call.

Instead I need to:

  • Check the address to be created then create one by one (and store the value to be used later)
  • Check the address to be updated then updated one by one (and store the value to be used later)
  • And finally do another call to chenge the name of the client.

So what I want to do is join this multiple http calls that can happen conditionally in one observable.

This is what I have so far:

updateClientAndClientAddresses(): Observable<Client> {       

   return of({}).pipe(
     ******* Conditionally make all the create addresses calls *******
     ******* Conditionally make all the update addresses calls *******
     *******   Then make the update name call *******

     switchMap(([updateNameResponse: Client, responseOfAllAddressesToBeCreated: Address, responseOfAllAddressesToUpdated: Address]) => {
    // Ideally here I will have the results of all the calls made so far.

    // Merge everything manually here
    return {
      ...updateClientCallResponse,
      addresses: [
        ...responseOfAllAddressesToBeCreated,
        ...responseOfAllAddressesToUpdated
      ]};
  }),
)
}

Just to reinforce:
Before I do the call to update the name I need to check if:

  • addressesToBeCreated.length if yes I need to do one particular call for every lenght of this array, wait for the response and store the result to be used latter on.

then I need to check if:

  • addressesToUpdated.length if yes I need to do another particular call vor every lenght of this array and wait for the response and store the result to be used latter on.

  • Finally I will do the call to update the name od the client, get the result and then merge with all the responses that I conditionally made before.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

成熟的代价 2025-02-10 04:53:20
  1. 将地址分为两组:要创建的地址,以及要更新的。

      const addressEstobecreated:address [] = [ / *要创建的地址列表 * /];
    const addresseStobeupdated:address [] = [ / *要更新的地址列表 * /];
     
  2. 分别收集创建和更新地址所需的HTTP请求。 (使用服务器响应内容的假设。)

      const createrequests:可观察&lt; address&gt; [] = adversionEstobecreated.map(
    (地址)=&gt; this.client.post(...)//

  1. Organize addresses into two groups: those to be created, and those to be updated.

    const addressesToBeCreated: Address[] = [ /* list of addresses to be created */ ];
    const addressesToBeUpdated: Address[] = [ /* list of addresses to be updated */ ];
    
  2. Collect the HTTP requests needed to create and update the addresses, respectively. (Assumptions were made with what the server response content will be.)

    const createRequests: Observable<Address>[] = addressesToBeCreated.map(
      (address) => this.client.post(...) // ???? request server to save the address, and respond with the created address resource
    );
    
    const updateRequests: Observable<Address>[] = addressesToBeUpdated.map(
      (address) => this.client.put(...) // ???? request server to update existing address, and respond with the updated address resource
    );
    
  3. Construct a pipeline using operators forkJoin and concatMap, in a way that tells RxJS to actually trigger sending the create and update requests, and then return said addresses that were created and updated.

    const savedAddresses$ = forkJoin(createRequests) // ???? trigger the bunch of HTTP requests that creates addresses
      .pipe(
        concatMap((createdAddresses) => {  // ???? now we have a list of created addresses
          return forkJoin(updateRequests)  // ???? next, trigger HTTP requests that updates addresses
            .pipe(
              map((updatedAddresses) => {  // ???? now we have the list of updated addresses
                return [                   // ???? emit a tuple of created and updated addresses down the pipeline
                  createdAddresses,
                  updatedAddresses
                ];
              })
            );
        })
      );
    

    savedAddresses$ will be an observable that emits an array of two elements: a list of created addresses, and list of updated addresses.

  4. Finally do another call to change the name of the client.

    const savedModels$ = savedAddresses$.pipe(
      concatMap((savedAddresses) => {
        return this.client.put(...)   // ???? request server to update client name, and return updated client model
          .pipe(
            map((updatedClient) => {  // ???? now we have the client object with updated name
              return [updatedClient, ...savedAddresses]; // ???? emit a tuple down the pipeline with three elements: client, list of created addresses, and list of updated addresses
            })
          );
      })
    );
    

    savedModels$ will be an observable that emits an array of three elements: client model with its name updated, list of addresses created, and list of addresses updated.

  5. At this point, you can finally "merge everything manually here." You can join data about the client, and addresses that have been created and updated however you like.

    updateClientAndClientAddresses(): Observable<Client> {
      ... // ???? code from previous steps
    
      return savedModels$.pipe(
        map(([updatedClient, createdAddresses, updatedAddresses]) => {
          return {
            ...updatedClient,
            address: [
              ...createdAddresses,
              ...updatedAddresses
            ]
          };
        })
      );
    }
    
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文