在Jquery循环中使用async/await的正确方法

knsnq2tg  于 2023-08-04  发布在  jQuery
关注(0)|答案(1)|浏览(176)

我在我的脚本中有下面的jQuery代码。在这里,我试图在saveQuestion函数内发生一系列 AJAX 调用时显示加载图标。
但是加载功能并没有发生,而是按顺序发生了 AJAX 调用。
我正在尝试下面的代码。请提出任何想法

$(document).on("click", ".update_qualify_question", function (e) {  

    var btnObj  = $(".update_qualify_question");
    var btnTxt = btnObj.text();
    btnObj.html('Processing <i class="fa fa-spinner fa-spin"></i>');
    btnObj.attr('disabled', 'disabled');
    
    (async function() {
        $(this).closest('.conditional_qa_portion').find(".current_question").each(async function(){
            await saveQuestion($(this), 1);
        })
    
    })();
       
        btnObj.html(btnTxt); 
        btnObj.removeAttr('disabled');  
                
});

字符串

s4n0splo

s4n0splo1#

这里发生的事情是你的函数没有等待异步代码的结果,这意味着你正在改变按钮文本,然后立即将其更改回来,这导致文本没有改变的外观。

btnObj.html('Processing <i class="fa fa-spinner fa-spin"></i>');
// not awaited so don't stop execution
(async function() {
  $(this)
    .closest('.conditional_qa_portion')
    .find(".current_question")
    .each(async function() {await saveQuestion($(this), 1);});
})();
// ran immediately
btnObj.html(btnText);

字符串
等待代码有两个问题,你在.each中有一个异步调用,它没有办法被等待,还有你创建并立即调用的匿名函数。
你可以使用async/await来做这样的事情:

$(document).on("click", ".update_qualify_question", async function (e) {  
    const btnObj  = $(e.currentTarget);
    const btnTxt = btnObj.text();
    btnObj.html('Processing <i class="fa fa-spinner fa-spin"></i>');
    btnObj.attr('disabled', 'disabled');
    // not sure what element you wanted to do closest on since you had nested function so this wasn't the button (which is what I believe you meant)
    const elms = btnObj      
        .closest('.conditional_qa_portion')
        .find(".current_question")
        .toArray();
    for(const elm of elms) {
        await saveQuestion($(elm), 1);
    }
    btnObj.html(btnTxt); 
    btnObj.removeAttr('disabled');              
});


有了这个,我们可以等到每个数据调用完成后再允许按钮被再次点击。我们使用.toArray()来获取列表,这样我们就可以在for of循环中等待结果,因为.each()没有办法等待结果。

相关问题