递归调用异步函数返回一个Promise [英] Recursively calling asynchronous function that returns a promise

查看:370
本文介绍了递归调用异步函数返回一个Promise的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图递归调用AWS的SNS listEndpointsByPlatformApplication.这将返回前100个端点,然后返回NextToken中的令牌(如果还有更多要返回的令牌)(详细信息:

I'm trying to recursively call AWS's SNS listEndpointsByPlatformApplication. This returns the first 100 endpoints then a token in NextToken if there are more to return (details: AWS SNS listEndpointsByPlatformApplication).

这是我尝试过的:

var getEndpoints = function(platformARN, token) {

  return new models.sequelize.Promise(function(resolve, reject) {
    var params = {
      PlatformApplicationArn: platformARNDev
    };
    if (token != null) {
      params['NextToken'] = token;
    }
    sns.listEndpointsByPlatformApplication(params, function(err, data) {
      if (err) {
        return reject(err);
      }
      else {
        endpoints = endpoints.concat(data.Endpoints); //save to global var
        if ('NextToken' in data) {
          //call recursively
          return getEndpoints(platformARN, data.NextToken);
        }
        else {
          console.log('trying to break out!');
          return resolve(true);          
        }
      }
    });
  });
}

我这样称呼:

getEndpoints(platformARNDev, null)
.then(function(ret) {
  console.log('HERE!');
}, function(err) {
  console.log(err);
});

问题是:第一次调用发生,然后递归调用发生,并且我收到消息trying to break out!,但是HERE!从未被调用.我的诺言如何恢复,我认为有些错误.

Problem is: the first call happens, then the recursive call happens, and I get the message trying to break out! but the HERE! never gets called. I've got something wrong with how my promises are returning I think.

感谢指针.

推荐答案

问题是您尝试解决/拒绝部分完成的查询.这是虚拟服务的完整工作示例.我将获取的数据封装到它自己的递归函数中,并且仅在我完全获取了所有数据或偶然发现错误时才进行解析/拒绝:

The problem is that you try and resolve/reject partially completed query. Here is a complete working example with dummy service. I incapsulated the data grabbing into it's own recursive function and only do resolve/reject when i've completely fetched all the data or stumbled upon an error:

// This is the mock of the service. It yields data and token if
// it has more data to show. Otherwise data and null as a token.
var dummyData = [0, 1, 2, 3, 4];
function dummyAsyncCall(token, callback) {
  token = token || 0;
  setTimeout(function() {
    callback({
        dummyDataPart: dummyData[token],
        token: (typeof (dummyData[token]) == 'undefined') ? null : (token + 1)
    });
  });
}

// Here is how you would recursively call it with promises:

function getAllData() {
  //data accumulator is sitting within the function so it doesn't pollute the global namespace.
  var dataSoFar = [];

  function recursiveCall(token, resolve, reject) {
    dummyAsyncCall(token, function(data) {
      if (data.error) {
        reject(data.error);
      }
      if (!data.token) {
        //You don't need to return the resolve/reject result.
        resolve(dataSoFar);
      } else {
        dataSoFar = dataSoFar.concat(data.dummyDataPart);
        recursiveCall(data.token, resolve, reject);
      }
    });
  }

  return new Promise(function(resolve, reject) {
    // Note me passing resolve and reject into the recursive call.
    // I like it this way but you can just store them within the closure for
    // later use
    recursiveCall(null, resolve, reject);
  });
}

//Here is the call to the recursive service.
getAllData().then(function(data) {
  console.log(data);
});

与我同在

这篇关于递归调用异步函数返回一个Promise的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆