多次运行API并将结果存储在数组中

huangapple go评论61阅读模式
英文:

Run an API multiple times and store the result in an array

问题

以下是已翻译的部分:

我想多次运行 API 调用,然后将 API 响应存储在数组/observable 中。

public getProgramNamesList() {
    for (let i = 0; i < this.totalPages; i++) {
        this.accountAdminApiService.getAccountAdminProgramsBySearch((i)).subscribe((programResults: ProgramSearchResults) => {
            if (programResults?.data?.length) {
                this.totalPages = Math.ceil(programResults.totalCount / this.pageSize);
                this.programResults$.next(programResults.data);
            }
        });
    }

    return this.programResults$;
}

我尝试了上面的代码。它只返回第一组结果,而且 API 没有多次运行。

英文:

I want to run an API call multiple times and then store the API response in an array/observable.

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

public getProgramNamesList() {
        for (let i = 0; i &lt; this.totalPages; i++) {                     

this.accountAdminApiService.getAccountAdminProgramsBySearch((i)).subscribe((programResults: ProgramSearchResults) => {
if (programResults?.data?.length) {
this.totalPages = Math.ceil(programResults.totalCount / this.pageSize);

                    this.programResults$.next(programResults.data);
                }
            });
        }

        return this.programResults$;
    }

<!-- end snippet -->

I tried the above code. It is only returning the first set of results and the API is not running multiple times.

答案1

得分: 1

你正在尝试在循环中实际同步选项,相反,你应该将多个异步操作转换为一个并订阅结果。如果我正确理解你的情况,这里是一个方法的演示:

const api$ = (i: number) => of(i).pipe(delay(100));
const results$ = new BehaviorSubject<number[]>([]);

function getProgramNamesList() {
  forkJoin(
    Array.from({ length: 100 }, (_, i) => i).map((i) => api$(i))
  ).subscribe(results$);
}
results$.subscribe(console.log);
// 打开右下角的控制台查看结果。

getProgramNamesList();
英文:

You are trying to do actually sync options in the loop - instead, you should convert multiple async actions to a single one and subscribe to the result. If I understand you situation correctly, here is a demo of one of the approaches

const api$ = (i: number) =&gt; of(i).pipe(delay(100));
const results$ = new BehaviorSubject&lt;number[]&gt;([]);

function getProgramNamesList() {
  forkJoin(
    Array.from({ length: 100 }, (_, i) =&gt; i).map((i) =&gt; api$(i))
  ).subscribe(results$);
}
results$.subscribe(console.log);
// Open the console in the bottom right to see results.

getProgramNamesList();


答案2

得分: 0

Sure, here are the translated parts:

Doing some logic for each call:

public yourFunction() {
    const idList = [1, 2, 3, 4, "test", "somethingElse"];
    from(idList)
      .pipe(
        concatMap((id) => this.http.get(`https://api.agify.io/?name=${id}`))
      )
      .subscribe(
        (character) => {
          // This will be triggered every time an http gets resolved.
          this.programResults$.next(programResults.data);
        }
      );
  }

Doing some logic at the end, when all the calls are done and the data is already retrieved:

public yourFunction() {
    const arrayCalls = [];
    for(let i=0; i<10; i++) {
      arrayCalls.push(this.http.get(`https://api.agify.io/?name=${i}`));
    }

    forkJoin(arrayCalls).subscribe(data => {
      // data is an array of results.
      // This is called just once
      this.programResults$.next(data)
    })
  }

You can check out the live example here.

英文:

Since I've no idea how you're using programResults$ there could be two ways of doing that:

Doing some logic for each calls :

public yourFunction() {
    const idList = [1, 2, 3, 4, &quot;test&quot;, &quot;somethingElse&quot;];
    from(idList)
      .pipe(
        concatMap((id) =&gt; this.http.get(`https://api.agify.io/?name=${id}`))
      )
      .subscribe(
        (character) =&gt; {
          // This will be triggered every time an http gets resolved.
          this.programResults$.next(programResults.data);
        }
      );
  }

Doing some logic at the end, when all the calls are done and the data is already retrieved:

public yourFunction() {
    const arrayCalls = [];
    for(let i=0; i&lt;10; i++) {
      arrayCalls.push(this.http.get(`https://api.agify.io/?name=${i}`));
    }

    forkJoin(arrayCalls).subscribe(data =&gt; {
      // data is an array of results.
      // This is called just once
      this.programResults$.next(data)
    })
  }

You can checkout the live example here

huangapple
  • 本文由 发表于 2023年4月13日 15:52:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/76002947.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定