Saya memiliki kode JavaScript berikut:
$('a.button').click(function(){
if (condition == 'true'){
function1(someVariable);
function2(someOtherVariable);
}
else {
doThis(someVariable);
}
});
Bagaimana saya bisa memastikan yang function2
dipanggil hanya setelah function1
selesai?
javascript
jquery
Rrryyyaaannn
sumber
sumber
function1
melakukan operasi async?Jawaban:
Tentukan panggilan balik anonim, dan buat function1 menerimanya:
sumber
...do stuff
berisi hal-hal yang tidak sinkron? Function2 masih tidak akan menyala saat diharapkan. Contoh dalam komentar saya di atas menunjukkan bahwa karenafoo()
fungsinya memiliki kode asinkron di dalamnya,bar()
tidak memecat kontennya setelahfoo()
konten selesai dieksekusi, bahkan menggunakan$.when().then()
untuk memanggil mereka satu demi satu. Jawaban ini hanya valid jika (dan hanya jika) semua hal di...do stuff
dalam kode Anda benar-benar sinkron.callBack()
setelah semua n asynchronous panggilan dilakukan. Karena OP belum menyebutkan apa yang dia lakukan dalam fungsinya, diasumsikan sebagai panggilan asinkron satu tingkat.Jika Anda menggunakan jQuery 1.5 Anda dapat menggunakan pola Tangguhan baru:
Edit: Tautan blog yang diperbarui:
Rebecca Murphy memiliki artikel bagus tentang ini di sini: http://rmurphey.com/blog/2010/12/25/deferreds-coming-to-jquery/
sumber
$.when(function1).then(function2);
(tanpa tanda kurung yang memanggil fungsi)?function1
harus mengembalikan janji. Dalam hal ini, itu haruslah fungsi yang dieksekusi, bukan referensi. Kapanresolve
dipanggil janji itu makafunction2
dieksekusi. Ini mudah dijelaskan dengan mengasumsikan bahwafunction1
memiliki panggilan ajax. Thedone
callback kemudian akan menyelesaikan janji. Saya harap itu jelas.Coba ini :
sumber
Jawaban ini menggunakan
promises
, fitur JavaScriptECMAScript 6
standar. Jika platform target Anda tidak mendukungpromises
, isi dengan PromiseJs .Janji adalah cara baru (dan jauh lebih baik) untuk menangani operasi asinkron dalam JavaScript:
Ini mungkin tampak seperti overhead yang signifikan untuk contoh sederhana ini, tetapi untuk kode yang lebih kompleks itu jauh lebih baik daripada menggunakan panggilan balik. Anda dapat dengan mudah membuat beberapa panggilan tidak sinkron menggunakan banyak
then
pernyataan:Anda juga dapat membungkus jQuery deferrds dengan mudah (yang dikembalikan dari
$.ajax
panggilan):Seperti @charlietfl catat,
jqXHR
objek dikembalikan dengan$.ajax()
mengimplementasikanPromise
antarmuka. Jadi sebenarnya tidak perlu untuk membungkusnyaPromise
, itu dapat digunakan langsung:sumber
Promise.resolve
pembungkus$.ajax
adalah anti-pola sejak$.ajax
mengembalikan janji masa laluPromise
, itu hanya mengimplementasikan antarmuka. Saya tidak yakin bagaimana perilakunya ketika meneruskan nyataPromise
kethen
metodenya, atau apa yangPromise.all
akan dilakukan jika ajqXHR
dan aPromise
diteruskan ke sana. Untuk itu saya perlu melakukan pengujian lebih lanjut. Tapi terima kasih atas petunjuknya, saya akan menambahkannya ke jawabannya!$.ajax.then
bukan hal baruAtau Anda dapat memicu acara khusus ketika satu fungsi selesai, kemudian ikat ke dokumen:
Dengan menggunakan metode ini, fungsi 'b' hanya dapat menjalankan fungsi SETELAH 'a', karena pemicu hanya ada ketika fungsi a selesai dieksekusi.
sumber
Anda bisa melakukannya seperti ini
sumber
Ini tergantung pada apa yang dilakukan function1.
Jika function1 melakukan beberapa javascript synchrounous sederhana, seperti memperbarui nilai div atau sesuatu, maka function2 akan diaktifkan setelah function1 selesai.
Jika function1 melakukan panggilan asinkron, seperti panggilan AJAX, Anda harus membuat metode "panggilan balik" (sebagian besar API ajax memiliki parameter fungsi panggilan balik). Kemudian panggil function2 di dalam callback. misalnya:
sumber
Jika metode 1 harus dijalankan setelah metode 2, 3, 4. Cuplikan kode berikut dapat menjadi solusi untuk ini menggunakan objek Ditangguhkan dalam JavaScript.
sumber
Jika function1 adalah beberapa fungsi sinkronisasi yang ingin Anda ubah menjadi async karena butuh beberapa waktu untuk menyelesaikannya, dan Anda tidak memiliki kontrol atasnya untuk menambahkan panggilan balik:
Outputnya adalah:
... dan setelah 2 detik:
Ini berfungsi karena memanggil window.setTimeout () akan menambahkan tugas ke loop tugas JS runtine, yang dibuat oleh panggilan async, dan karena prinsip dasar "run-to-completion" dari runtime JS memastikan bahwa onClick () tidak pernah terputus sebelum berakhir.
Perhatikan bahwa ini lucu karena mungkin kode ini sulit dimengerti ...
sumber