Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I have a function

this.config.apiFunc = (pageNo) => this.somePaginatedCall({
  page: {
    number: pNo,
    size: 10
  }
})

Now, I want to fetch the data in a batch of 5 pages (by maintaining the sequence). I added a delay of 2000ms for the sake of testing. I created

config = {
  apiFunc: any,
  data: []
}

async getData(){
  const pageGroupList = [
    [1,2,3,4],
    [5,6,7,8]
  ];
  const groupedPromise = [];
  groupedPromise.push(this.pageGroupList.map(pageNo => this.config.apiFunc(pageNo)));  //<-- This is making network request 
  // because I am trigerring the function call with ()
  await this.asyncForEach(groupedPromise,this.fetchInBatch.bind(this)); 
}

private asyncForEach(promiseList, func): Promise<any> {
  return promiseList.reduce((p,apiList) => {
     return p.then(this.sleep(2000)).then(() => func(apiList));
  }, Promise.resolve());
}

private fetchInBatch(apiList) {
  return Promise.all(apiList).then((res: any) => {
    // this gets called after every 2 secs but I do not see any call in Network tab
    this.config.data = [...this.config.data , ...[].concat(...res.map(r => r.data))];
  }) 
}
  
sleep(ms) {
  return (x) => new Promise(resolve => setTimeout(() => resolve(x), ms))
}

The problem is that I am making API request at groupedPromise.push(this.pageGroupList.map(pageNo => this.config.apiFunc(pageNo))) which I should not.

The data although loads as expected (after 2000 ms delay) but the network calls are already made.

I want to load the data after the 1st batch of pages is loaded (1,2,3,4) . In this example, after 2 secs.

Problem is that I want to pass pageNo to each API call before I invoke the function. I am slightly confused.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
151 views
Welcome To Ask or Share your Answers For Others

1 Answer

Try to do it like below. I have moved the map function inside the Promise.all

 async getData(){
   const pageGroupList = [
      [1,2,3,4],
      [5,6,7,8]
   ];
   this.asyncForEach(pageGroupList,this.fetchInBatch.bind(this)); 
 }

 private asyncForEach(pageGroupList, execFunc) {
    return pageGroupList.reduce((p,pageGroup) => {
        return p.then(() => execFunc(pageGroup));
    }, Promise.resolve());
  }

  private fetchInBatch(pageGroupList) {
    return Promise.all(pageGroupList.map(pageNo => this.config.apiFunc(pageNo))).then((res: any) => {
      this.config.data = [...this.config.data, ...[].concat(...res.map(r => r.data))];
    }) 
  }



与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...