【问题标题】:How to change Promise.all to send requests one by one如何更改 Promise.all 以一一发送请求
【发布时间】:2019-11-29 13:35:44
【问题描述】:

我有一组分块数据,我需要一次上传一个块。当前的实现我用它来封装 Promise.all() 中的逻辑,因为我需要返回 promise 的结果, 这种方法的问题是所有上传都是异步完成的,导致超时错误,因为服务器无法同时处理所有请求,我该如何修改这个方法,以便一次上传一个块? .

我的代码:

var chunks = _.chunk(variableRecords, 30);
return Promise.all(
        chunks.map(chunk => this.portalService.updateDataForChart(variableId, chunk)))
        .then((updateRes: boolean[]) => {
          if (updateRes.every(updateStatus => updateStatus)) {
            return this.executeRequest<HealthDataSource, boolean>({
              path: `/variable/user/datasources/${dataSource.identifier}`,
              method: 'PUT',
              body: {
                libelle: dataSource.datasource.libelle,
                type: dataSource.datasource.type,
                lastSyncDate: Math.max(maxDate, dataSource.datasource.lastSyncDate)
              },
              headers: this.getHeaders()
            });
          } else {
            return false;
          }
        });

【问题讨论】:

标签: javascript typescript promise lodash


【解决方案1】:

您在 SEQUENCE 中需要它们,因为 of 是要走的路:

async function chunksSequence(chunks) {
  for(const chunk of chunks) {
    await // your other code here
  }
};

如果需要退货

async function chunksSequence(chunks) {
  let results = []
  for(const chunk of chunks) {
    let result = await // your other code here
    results.push(result)
  }
  return results 
};

因为退货承诺中需要评论

async function chunksSequence(chunks) {
 return new Promise((resolve, reject)=>{
    let results = []
    for(const chunk of chunks) {
      let result = await // your other code here
      results.push(result)
    }
    resolve(results) 
  }
};

【讨论】:

  • 最后如何得到所有结果?
  • @Weedoze,只需在循环之前添加一个收集器数组,将每个结果推送到它并在函数结束时返回。
  • @CerebralFart 确实,最好将此部分添加到代码中,因为 OP 需要处理最终结果
  • 编辑完成,返回部分,如有需要请提供反馈:)
  • 返回类型应该是 Promise,因为我将在其上使用 .then 来执行 PUT 请求
【解决方案2】:

您可以在Array.reduce() 的帮助下完成此操作

const chunks = _.chunk(variableRecords, 30);
return tasks.reduce((promiseChain, currentTask) => {
    return promiseChain.then(chainResults =>
        currentTask.then(currentResult =>
            [ ...chainResults, currentResult ]
        )
    );
}, Promise.resolve([])).then(arrayOfResults => {
    // Do something with all results
});

来源:https://decembersoft.com/posts/promises-in-serial-with-array-reduce/

【讨论】:

  • 这里假设variableRecords是一个promise数组,其中已经建立了从服务器请求的过程。它仍然会出现与 OP 相同的问题,因为服务器无法同时处理所有请求。
【解决方案3】:

如果你不/不能使用await,你可以使用类似的东西

function runSequenceItem(chunks, index) {
 return new Promise(chunks[index])
  .then(res => {
     index ++
     if (index < chunks.length) {
       return runSequence(chunks[index], index + 1)
     } else {
       // this is not needed actually
       return 'done'
     }
   })
}

function runInSequence(chunks) {
 return runSequenceItem(chunks, 0)
}

如果您还需要结果,则可以在递归结束时返回一个数组runInSequence

    function runSequenceItem(chunks, index, results) {
 return new Promise(chunks[index])
  .then(res => {
     results.push(res)
     index ++
     if (index < chunks.length) {
       return runSequence(chunks[index], index + 1)
     } else {
       return results
     }
   })
}

function runInSequence(chunks) {
 return runSequenceItem(chunks, 0, [])
}

然后在最后检索它

let results = runInSequence(chunks)

【讨论】:

    猜你喜欢
    • 2020-10-31
    • 2021-10-26
    • 2014-02-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多