ค้นหาเว็บไซต์

javascript - เรียกใช้ฟังก์ชันหลังจากฟังก์ชันก่อนหน้าทำงานเสร็จ


ฉันมีโค้ด JavaScript ดังต่อไปนี้:

$('a.button').click(function(){
    if (condition == 'true'){
        function1(someVariable);
        function2(someOtherVariable);
    }
    else {
        doThis(someVariable);
    }
});

ฉันจะสามารถมั่นใจได้อย่างไรว่า function2 จะถูกเรียกก็ต่อเมื่อ function1 ทำงานเสร็จแล้วเท่านั้น?

คำตอบ #1

ระบุการเรียกกลับที่ไม่ระบุชื่อ และทำให้ function1 รับมันได้:

$('a.button').click(function(){
    if (condition == 'true'){
        function1(someVariable, function() {
          function2(someOtherVariable);
        });
    }
    else {
        doThis(someVariable);
    }
});


function function1(param, callback) {
  ...do stuff
  callback();
} 

คำตอบ #2

ถ้าคุณกำลังใช้ jQuery 1.5 คุณสามารถใช้รูปแบบ Deferreds ใหม่ได้:

$('a.button').click(function(){
    if(condition == 'true'){
        $.when(function1()).then(function2());
    }
    else {
        doThis(someVariable);
    }
});

แก้ไข: ลิงก์บล็อกที่อัปเดต:

รีเบคก้า เมอร์ฟี มีบทความที่น่าสนใจเกี่ยวกับเรื่องนี้ที่นี่: http://rmurphey.com/blog/2010/12/25/deferreds-coming-to-jquery/

คำตอบ #3

ลองอันนี้:

function method1(){
   // some code

}

function method2(){
   // some code
}

$.ajax({
   url:method1(),
   success:function(){
   method2();
}
})

คำตอบ #4

คำตอบนี้ใช้ promises ซึ่งเป็นคุณสมบัติของ JavaScript ในมาตรฐาน ECMAScript 6 หากแพลตฟอร์มเป้าหมายของคุณไม่รองรับ promises ให้ใช้ PromiseJs เพื่อเติมเต็ม

สัญญาเป็นวิธีใหม่ (และดีกว่ามาก) ในการจัดการการทำงานแบบอะซิงโครนัสใน JavaScript:

$('a.button').click(function(){
    if (condition == 'true'){
        function1(someVariable).then(function() {
            //this function is executed after function1
            function2(someOtherVariable);
        });
    }
    else {
        doThis(someVariable);
    }
});


function function1(param, callback) {
    return new Promise(function (fulfill, reject){
        //do stuff
        fulfill(result); //if the action succeeded
        reject(error); //if the action did not succeed
    });
} 

นี่อาจดูเหมือนเป็นภาระงานที่มากเกินไปสำหรับตัวอย่างง่ายๆ นี้ แต่สำหรับโค้ดที่ซับซ้อนมากขึ้นจะดีกว่าการใช้ callback อย่างมาก คุณสามารถเชื่อมต่อการเรียกใช้งานแบบอะซิงโครนัสหลายครั้งได้อย่างง่ายดายโดยใช้คำสั่ง then หลายคำสั่ง:

function1(someVariable).then(function() {
    function2(someOtherVariable);
}).then(function() {
    function3();
});

คุณยังสามารถห่อ jQuery deferreds ได้อย่างง่ายดาย (ซึ่งถูกส่งกลับมาจากการเรียก $.ajax)

Promise.resolve($.ajax(...params...)).then(function(result) {
    //whatever you want to do after the request
});

ตามที่ @charlietfl กล่าว วัตถุ jqXHR ที่ส่งกลับโดย $.ajax() ใช้อินเทอร์เฟซ Promise ดังนั้นจึงไม่จำเป็นต้องห่อมันใน Promise แต่อย่างใด มันสามารถใช้งานโดยตรงได้:

$.ajax(...params...).then(function(result) {
    //whatever you want to do after the request
});

คำตอบ #5

หรือคุณสามารถเรียกใช้อีเวนต์แบบกำหนดเองเมื่อฟังก์ชันหนึ่งเสร็จสิ้น แล้วจากนั้นผูกมันกับเอกสาร:

function a() {
    // first function code here
    $(document).trigger('function_a_complete');
}

function b() {
    // second function code here
}

$(document).bind('function_a_complete', b);

โดยใช้วิธีนี้ ฟังก์ชัน 'b' จะสามารถทำงานได้ก็ต่อเมื่อฟังก์ชัน 'a' ทำงานเสร็จแล้วเท่านั้น เนื่องจากทริกเกอร์จะมีอยู่เฉพาะเมื่อฟังก์ชัน a ทำงานเสร็จ

คำตอบ #6

คุณสามารถทำแบบนี้ได้

$.when(funtion1()).then(function(){
    funtion2();
})

บทความที่เกี่ยวข้อง