繁体   English   中英

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

[英]Javascript: Recursive function with promise and resolve when count is reached

我一直在尝试构建一个已定义为 promise 的递归 function。

我无法在下面的代码上应用递归模式,即使loopFor初始化为20 ,我也只循环了一次我错过了什么?

要求: 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));
                };
            });

    });
};

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

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

Remove first call to resolve应该可以解决您的问题。


你在评论中说:

使用 async/await 意味着重写整个程序

不,你对 async/await 的理解是错误的。 任何异步 function 都会自动返回 function 的 promise,这符合您的要求。 Async/await 只是 promise 之上的语法糖。

这意味着您可以安全地重写 ONLY receivingMessages function 而无需修改调用它的其他地方。

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

您的代码的问题是,在 client.send promise 解析之后的 then 回调中的 resolve 调用返回调用 receivingMessages 而不是 receivingMessages promise 本身的结果。 这导致递归循环只执行一次。

要解决此问题,您可以更改 resolve 调用以直接返回调用 receivingMessages 的结果:

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

这将导致 receivingMessages function 以递归方式被调用,直到 loopFor 达到 1。

您可能还想考虑向 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” 达到价值后解决递归承诺 在递归promise函数中未调用解析 递归函数中的 JavaScript promise 解决递归函数捕获中的承诺 在 JavaScript 中,如何在 `parent()` 返回 Promise 时实现递归 `ancestors()` 函数 在Javascript Promise中返回&#39;resolve&#39;函数 如何解决递归承诺? 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> 调用包含Java承诺的递归函数
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM