递归调用异步函数返回一个Promise [英] Recursively calling asynchronous function that returns a 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屋!