【问题标题】:Recursion with promises on async calls在异步调用中使用 Promise 进行递归
【发布时间】:2019-05-16 15:43:52
【问题描述】:

我正在使用我用作数据源的外部 api。该 api 根据分页类型返回其数据。

所以我可以获取第 1、2、3 页等的数据。但我遇到的问题是我需要一次所有数据,api 不支持这个所以我自己写。

我已经做了实际的调用代码:

function getTransactionPart(start){
        return new Promise(function(resolve, reject) {

            const options = {
                url: 'myurl?limit=40&start='+start,
                json: true
            };

            let result = {total_transactions : 0, transactions : []};

            request(options, function (error, response, body) {

                if (error) {
                    return reject(result);
                }

                body.data.forEach(function (transaction) {
                        result.transactions.push({
                            timestamp: transaction.timestamp,
                            amount: transaction.amount,
                            confirmed: transaction.confirmed
                        });
                });

                result.total_transactions = body.total

                return resolve(result);
            })
        })
    }

上面的代码以我给出的限制返回了预期的结果。此外,当超过 40 时,我会返回一个号码(result.total_transactions),我需要以 40 作为开始等再次拨打电话。

我需要合并的代码:

 function getTransactions(start) {
        return new Promise(function(resolve, reject) {

            getTransactionPart(start).then(result => {
                if(result.total_transactions > 40) {
                    //next call
                } else {
                    // return all?
                }
                console.log(result)
            }).catch(error => {
                console.error(error);
                return r.json({

                })
            });

        })
    }

所以我使用 getTransactionPart(0) 进行第一次调用,之后方法本身需要将所有子调用的结果组合起来,并按预期返回整个结果。如何使用递归和承诺来做到这一点?

【问题讨论】:

标签: javascript recursion ecmascript-6 promise


【解决方案1】:

如果您使用async 函数和await 请求,这会更容易:

  async function getTransactions(start) {
    const result = [];
    for(let pos = start; ; pos += 40) {
      const { total_transactions, transactions } = await getTransactionPart(pos);
      result.push(...transactions);

      if(total_transactions < 40) break;
    }
    return result;
 }

当然,您也可以递归地执行此操作,但您真的需要这样做吗?

async function getTransactions(start) {
  const { total_transactions, transactions } = await getTransactionPart(pos);
  if(total_transactions < 40) 
     return transactions;

  return transactions.concat(await getTransactions(start + 40));
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-02-10
    • 1970-01-01
    • 2020-02-08
    • 1970-01-01
    • 2015-07-02
    • 2018-01-30
    • 2017-10-28
    • 2015-08-27
    相关资源
    最近更新 更多