Javascript:递归函数,在达到计数时进行承诺和解析

b0zn9rqh  于 2023-01-07  发布在  Java
关注(0)|答案(2)|浏览(127)

我一直在尝试构建一个已经定义为promise的递归函数。
我还不能在下面的代码中应用递归模式,它是只循环一次即使loopFor是在20初始化的,我错过了什么?
要求:receivingMessages必须是一个承诺。

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));
                };
            });

    });
};
p4rjhz4m

p4rjhz4m1#

在第一个then回调client.send(cmd).then(data => …中,你调用了return resolve(globalMessageArray)。这有效地缩短了你的循环,因为一个promise只能调用resolve一次。之后调用resolve没有任何效果。

client.send(cmd).then((data) => {
    …
    return globalMessageArray;
}, …

删除对resolve的第一个调用应该可以解决您的问题。
你在评论中说:
使用async/await意味着重写整个程序
不,你对async/await的理解是错误的,任何async函数都自动是一个承诺返回函数,这符合你的要求,Async/await只是承诺之上的语法糖。
这意味着您可以安全地重写ONLY receivingMessages函数,而无需修改调用它的其他地方。
虽然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)
    };
};
pqwbnv8z

pqwbnv8z2#

您的代码问题在于,在客户端.send promise resolve之后,then回调中的resolve调用返回的是调用receivingMessages的结果,而不是receivingMessages promise本身。这导致递归循环仅执行一次。
要解决此问题,您可以更改resolve调用以直接返回调用receivingMessages的结果:

return receivingMessages(params, loopFor - 1, globalMessageArray);

这将导致以递归方式调用receivingMessages函数,直到loopFor达到1。
您可能还需要考虑向函数添加一个基本条件以确保它终止,例如添加一个loopFor小于或等于0的检查条件,并在这种情况下返回globalMessageArray。

相关问题