简体   繁体   English

Javascript:递归 function 与 promise 并在达到计数时解析

[英]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。

JavaScript计数器,一定时数到3<div> 到达了</div><div id="text_translate"><p>我很难解决这个问题。 所以我得到了计数器,我想在用户向下滚动页面并达到某个 class 后从 0 慢慢计数到 3,在我的例子中是“.domov2”</p><p> 如果我删除 API (EventListener),那么计数器工作得很好,但它已经在站点加载后立即开始计数。</p><p> 我设法做到了,但是当我向下滚动时不是执行 1 次,function 在到达 div 后执行了很多次滚动(我对 API 真的很糟糕)。 如何限制 function 执行 1 次并使其仅在条件下运行。</p><p> HTML:</p><pre class="lang-html prettyprint-override"> <section class="domov2"> Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. </section> <div id="counter" data-target="3"> -1 </div></pre><p> JavaScript</p><pre> $(window).bind('scroll', function() { if($(window).scrollTop() >= $('.domov2').offset().top + $('.domov2').outerHeight() - window.innerHeight) { // create function startCount() const startCount = function() { // get number value from data-target and current number const target = +counter.getAttribute('data-target'); const count = +counter.innerText; // if count<target if (count < target) { // add to current value +1 var sestevek = count + 1 // replace current value in html with recently updated value "sestevek" counter.innerText = sestevek; // slow down condition for 0.3s setTimeout(startCount, 300); } else { //if current value is = target, then keep target counter.innerText = target; }}; //execute function startCount(); } });</pre></div> - JavaScript counter, count to 3 when certain <div> is reached

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 JavaScript:具有Promise的递归函数,resolve返回“ undefined” - JavaScript: Recursive function with Promise, resolve returns “undefined” 达到价值后解决递归承诺 - Resolve recursive Promise after value is reached 在递归promise函数中未调用解析 - Resolve not called in a recursive promise function 递归函数中的 JavaScript promise - JavaScript promise in recursive function 解决递归函数捕获中的承诺 - Resolve a promise from a recursive function catch 在 JavaScript 中,如何在 `parent()` 返回 Promise 时实现递归 `ancestors()` 函数 - In JavaScript, how to implement a recursive `ancestors()` function when `parent()` returns a Promise 在Javascript Promise中返回&#39;resolve&#39;函数 - Returning 'resolve' function in Javascript Promise 如何解决递归承诺? - How to resolve recursive promise? JavaScript计数器,一定时数到3<div> 到达了</div><div id="text_translate"><p>我很难解决这个问题。 所以我得到了计数器,我想在用户向下滚动页面并达到某个 class 后从 0 慢慢计数到 3,在我的例子中是“.domov2”</p><p> 如果我删除 API (EventListener),那么计数器工作得很好,但它已经在站点加载后立即开始计数。</p><p> 我设法做到了,但是当我向下滚动时不是执行 1 次,function 在到达 div 后执行了很多次滚动(我对 API 真的很糟糕)。 如何限制 function 执行 1 次并使其仅在条件下运行。</p><p> HTML:</p><pre class="lang-html prettyprint-override"> <section class="domov2"> Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. </section> <div id="counter" data-target="3"> -1 </div></pre><p> JavaScript</p><pre> $(window).bind('scroll', function() { if($(window).scrollTop() >= $('.domov2').offset().top + $('.domov2').outerHeight() - window.innerHeight) { // create function startCount() const startCount = function() { // get number value from data-target and current number const target = +counter.getAttribute('data-target'); const count = +counter.innerText; // if count<target if (count < target) { // add to current value +1 var sestevek = count + 1 // replace current value in html with recently updated value "sestevek" counter.innerText = sestevek; // slow down condition for 0.3s setTimeout(startCount, 300); } else { //if current value is = target, then keep target counter.innerText = target; }}; //execute function startCount(); } });</pre></div> - JavaScript counter, count to 3 when certain <div> is reached 调用包含Java承诺的递归函数 - Calling a recursive function that includes a promise in Javascript
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM