【问题标题】:Sequential Promise All call with a variable param带有变量参数的顺序 Promise All 调用
【发布时间】:2021-10-30 03:42:16
【问题描述】:

我有一个函数

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

现在,我想以 5 页为一组获取数据(通过维护序列)。为了测试,我添加了2000ms 的延迟。我创造了

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))
}

问题是我不应该在groupedPromise.push(this.pageGroupList.map(pageNo =&gt; this.config.apiFunc(pageNo))) 发出 API 请求。

数据虽然按预期加载(延迟 2000 毫秒后),但已经进行了网络调用。

我想在第一批页面加载后加载数据 (1,2,3,4) 。在本例中,2 秒后。

问题是我想在调用函数之前将pageNo 传递给每个 API 调用。我有点困惑。

【问题讨论】:

    标签: javascript typescript async-await promise


    【解决方案1】:

    尝试像下面那样做。我已将map 函数移到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))];
        }) 
      }
    
    
    

    【讨论】:

      【解决方案2】:

      我认为你的问题是你正在映射调用的结果,但你应该映射函数,试试这个:

      //Returns [fn1, fn2, ...];
      groupedPromise.push(...this.pageGroupList.map(pageNo => () => this.config.apiFunc(pageNo)));
      

      或者更好:

      async getData(){
          const pageGroupList = [
            [1,2,3,4],
            [5,6,7,8]
          ];
          const groupedPromise = this.pageGroupList.map(pageNo => () => 
      this.config.apiFunc(pageNo)));
          await this.asyncForEach(groupedPromise,this.fetchInBatch.bind(this)); 
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-08-03
        • 1970-01-01
        • 1970-01-01
        • 2016-08-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多