簡體   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