[英]Javascript: Recursive function with promise and resolve when count is reached
I am stuck trying to build a recursive function that is already defined as a promise.我一直在尝试构建一个已定义为 promise 的递归 function。
I have not been able to apply the recursive pattern on the code below which is looping only once even though loopFor
is initialised at 20
what I am missing?我无法在下面的代码上应用递归模式,即使loopFor
初始化为20
,我也只循环了一次我错过了什么?
Requirement: receivingMessages
must be a promise.要求: receivingMessages
必须是一个promise。
let globalMessageArray = [];
let count = 0;
let loopFor = 20;
function receivingMessages(params, loopFor, globalMessageArray) {
return new Promise((resolve, reject) => {
const command = new ReceiveMessageCommand(params);
client.send(command).then(
(data) => {
if (data && data.Messages && data.Messages.length) {
data.Messages.forEach(msg => {
globalMessageArray.push(msg);
});
};
return resolve(globalMessageArray);
},
(error) => {
return reject(error);
}).then(
(globalMessageArray) => {
count = count + 1;
console.log("Loop Count: " + count); // always returns 1
if (loopFor === 1) {
return resolve(globalMessageArray);
} else {
return resolve(receivingMessages(params, loopFor - 1, globalMessageArray));
};
});
});
};
In the first then callback client.send(cmd).then(data => …
you return resolve(globalMessageArray)
. This effectively short-circuit your loop, because a promise can only resolve
once. Later call of resolve
has no effect.在第一个 then 回调client.send(cmd).then(data => …
你return resolve(globalMessageArray)
。这有效地缩短了你的循环,因为 promise 只能resolve
一次。稍后调用resolve
没有效果。
client.send(cmd).then((data) => {
…
return globalMessageArray;
}, …
Remove first call to resolve
should solve your problem. Remove first call to resolve
应该可以解决您的问题。
You said in comment:你在评论中说:
Using async/await would imply to rewrite the whole program使用 async/await 意味着重写整个程序
No, your understanding of async/await is wrong.不,你对 async/await 的理解是错误的。 Any async function is automatically a promise returning function, which meets your requirement.任何异步 function 都会自动返回 function 的 promise,这符合您的要求。 Async/await is just syntax sugar on top of promise. Async/await 只是 promise 之上的语法糖。
This means you can safely rewrite ONLY receivingMessages
function without needing to modify other places that call it.这意味着您可以安全地重写 ONLY receivingMessages
function 而无需修改调用它的其他地方。
Although there is nothing wrong with vanilla promise, rewriting to async/await will make your code so much cleaner.尽管 vanilla promise 没有任何问题,但重写为 async/await 将使您的代码更加清晰。
async function receivingMessages(params, loopFor, globalMessageArray) {
const command = new ReceiveMessageCommand(params);
const data = await client.send(command);
if (data && data.Messages && data.Messages.length) {
data.Messages.forEach(msg => {
globalMessageArray.push(msg);
});
}
if (loopFor === 1) {
return globalMessageArray;
} else {
return receivingMessages(params, loopFor - 1, globalMessageArray)
};
};
The issue with your code is that the resolve call in the then callback after the client.send promise resolves is returning the result of calling receivingMessages instead of the receivingMessages promise itself.您的代码的问题是,在 client.send promise 解析之后的 then 回调中的 resolve 调用返回调用 receivingMessages 而不是 receivingMessages promise 本身的结果。 This causes the recursive loop to only execute once.这导致递归循环只执行一次。
To fix this, you can change the resolve call to return the result of calling receivingMessages directly:要解决此问题,您可以更改 resolve 调用以直接返回调用 receivingMessages 的结果:
return receivingMessages(params, loopFor - 1, globalMessageArray);
This will cause the receivingMessages function to be called in a recursive manner until loopFor reaches 1.这将导致 receivingMessages function 以递归方式被调用,直到 loopFor 达到 1。
You may also want to consider adding a base case to the function to ensure that it terminates, such as adding a check for loopFor being less than or equal to 0 and returning the globalMessageArray in that case.您可能还想考虑向 function 添加基本情况以确保它终止,例如添加检查 loopFor 是否小于或等于 0 并在这种情况下返回 globalMessageArray。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.