Apakah ada alasan untuk menggunakan XMLHttpRequest sinkron?

88

Tampaknya sebagian besar orang melakukan permintaan asinkron dengan XMLHttpRequest, tetapi fakta bahwa ada kemampuan untuk melakukan permintaan sinkron menunjukkan mungkin ada alasan yang valid untuk melakukannya. Jadi, apa alasan yang valid itu?

Darrell Brogdon
sumber
1
Itu pertanyaan yang cukup bagus! Saya tidak berpikir jawabannya akan sangat menarik, tetapi pertanyaan yang bagus. Sudahkah Anda mencoba panggilan sinkron untuk melihat apa yang akan terjadi?
Tad Donaghe
3
Panggilan sinkron memblokir browser yang mengarah ke pengalaman pengguna yang buruk. Demikian pertanyaan saya. Saya tidak bisa memikirkan alasan bagus untuk menggunakannya.
Darrell Brogdon
2
Jawaban semi-serius: mungkin hanya untuk mengisi bab yang muncul sebelum permintaan asinkron di buku JavaScript apa pun yang Anda baca.
Ben James
Secara pribadi, saya ingin menggunakan beberapa ajax sinkron untuk menggabungkan beberapa panggilan ke fungsi server tanpa harus menulis permintaan untuk setiap panggilan.
Paul Ishak
menjalankan kode secara lokal, terutama untuk framework dan alat dev internal.
pengguna2800679

Jawaban:

26

Saya pikir mereka mungkin menjadi lebih populer seiring kemajuan standar HTML 5. Jika aplikasi web diberi akses ke pekerja web, saya dapat memperkirakan pengembang menggunakan pekerja web khusus untuk membuat permintaan sinkron, seperti yang dikatakan Jonathan, untuk memastikan satu permintaan terjadi sebelum yang lain. Dengan situasi saat ini dari satu utas, ini adalah desain yang kurang ideal karena diblokir hingga permintaan selesai.

DC
sumber
16
Saya berasumsi yang dia maksud adalah 'Pekerja Web'
evilpie
Saya pikir titik suling. Di UI Thread, Buat thread atau semacam tugas asinkron. Jika di utas sudah, gunakan disinkronkan dalam banyak kasus. Utas jauh lebih "ramah blok"
HaMMeReD
Ini adalah jawaban lama, tetapi komentar ini berlaku bahkan di masa lalu, bahkan sebelum HTML5, browser menyediakan 2 utas untuk membuat permintaan. Saya menulis skrip pool koneksi untuk memanfaatkan keduanya, karena bahkan dengan permintaan async, dengan satu koneksi, Anda dapat mengikat browser. Memanfaatkan keduanya memungkinkan lebih banyak data untuk didorong / ditarik melalui jalur; tapi iirc, saya pikir permintaan sinkronisasi masih mengikat browser.
vol7ron
Firefox (dan kemungkinan semua browser non-IE) tidak mendukung timeOut XHR asinkron. HTML5 WebWorkers mendukung waktu tunggu. Jadi, Anda mungkin ingin menggabungkan permintaan XHR sinkronisasi ke WebWorker dengan waktu tunggu untuk mengimplementasikan XHR seperti asinkron dengan perilaku waktu tunggu.
Dmitry Kaigorodov
1
-1. Ini bukan jawaban yang bagus dan seluruh diskusi tentang utas hanya membingungkan masalah. Jawaban Sami di bawah ini sebenarnya jauh lebih baik.
Stijn de Witt
30

XHR sinkron berguna untuk menyimpan data pengguna. Jika Anda menanganibeforeunload acara tersebut, Anda dapat mengunggah data ke server saat pengguna menutup halaman.

Jika ini dilakukan dengan menggunakan opsi async, maka halaman bisa ditutup sebelum permintaan selesai. Melakukan ini secara sinkron memastikan permintaan selesai atau gagal dengan cara yang diharapkan.

Sami Samhuri
sumber
4
Diedit: Saya menyadari Anda baru saja membuang txt dari pengguna HN yang malas, tetapi sedikit waktu untuk menyusunnya dengan baik dihargai di sini di SO.
Frank Krueger
Tapi sebenarnya ini satu-satunya alasan sah yang saya lihat sejauh ini.
Stijn de Witt
@ Frank Krueger Apa itu HN?
Douglas Diadakan
1
@DouglasHeld Sebuah situs web bernama Hacker News di news.ycombinator.com
Sami Samhuri
13

Memperbarui:

Di bawah ini mengisyaratkan - tetapi tidak berhasil menyampaikan - bahwa dengan munculnya penanganan permintaan asinkron yang lebih baik, sebenarnya tidak ada alasan untuk menggunakan permintaan sinkron, kecuali jika bermaksud untuk dengan sengaja memblokir pengguna agar tidak melakukan apa pun sampai permintaan selesai - terdengar berbahaya: )

Meskipun, ini mungkin terdengar buruk, ada kalanya penting bahwa permintaan (atau serangkaian permintaan) terjadi sebelum pengguna meninggalkan halaman, atau sebelum tindakan dilakukan - memblokir eksekusi kode lain (misalnya, mencegah tombol kembali) dapat kemungkinan mengurangi kesalahan / pemeliharaan untuk sistem yang dirancang dengan buruk ; Yang mengatakan, saya belum pernah melihatnya di alam liar dan menekankan bahwa hal itu harus dihindari.

Library, seperti promise , berpura-pura sinkronisitas dengan proses merangkai melalui callback. Ini sesuai dengan sebagian besar kebutuhan pengembangan di mana keinginannya adalah untuk memesan, acara non-pemblokiran yang memungkinkan browser mempertahankan daya tanggap pengguna (UX yang baik).

Sebagai dinyatakan dalam dokumen Mozilla ada kasus di mana Anda harus menggunakan permintaan sinkron; Namun, tercantum juga solusi yang menggunakan beacon (tidak tersedia di IE / Safari) untuk kasus seperti itu. Sementara ini eksperimental, jika itu pernah mencapai penerimaan standar, itu mungkin bisa menempatkan paku di peti mati permintaan sinkron.


Anda ingin melakukan panggilan sinkron dalam segala jenis pemrosesan seperti transaksi, atau di mana pun urutan operasi diperlukan.

Misalnya, Anda ingin menyesuaikan acara agar Anda keluar setelah memutar lagu. Jika operasi logout terjadi lebih dulu, maka lagu tersebut tidak akan pernah dimainkan. Ini membutuhkan sinkronisasi permintaan.

Alasan lain adalah saat bekerja dengan WebService, terutama saat melakukan matematika di server.

Contoh: Server memiliki variabel dengan nilai 1.

 Step (1) Perform Update: add 1 to variable
 Step (2) Perform Update: set variable to the power of 3
 End Value: variable equals 8

Jika Langkah (2) terjadi lebih dulu, maka nilai akhirnya adalah 2, bukan 8; Oleh karena itu, urutan operasi penting dan sinkronisasi diperlukan.


Ada beberapa kali panggilan sinkron dapat dibenarkan dalam contoh dunia nyata yang umum. Mungkin saat mengklik login dan kemudian mengklik bagian situs yang mengharuskan pengguna untuk login.

Seperti yang dikatakan orang lain, itu akan mengikat browser Anda, jadi jauhi itu di mana Anda bisa.

Namun, alih-alih panggilan sinkron, sering kali pengguna ingin menghentikan peristiwa yang sedang dimuat dan kemudian melakukan operasi lain. Di satu sisi, ini adalah sinkronisasi, karena acara pertama ditutup sebelum acara kedua dimulai. Untuk melakukan ini, gunakan metode abort () pada objek koneksi xml.

vol7ron
sumber
1
Saya pikir ini harus menjadi jawaban yang benar
3
@Zack: itu contoh yang bagus, namun Anda mungkin dapat melakukan hal yang sama dengan panggilan asinkron bergantung pada acara yang memanggilnya.
vol7ron
3
+1 Ada kasus valid bahwa kondisi balapan logis dapat dihasilkan dari permintaan server asinkron ... Namun, solusinya tidak harus sinkronisitas. Kecuali permintaan Anda ditangani dari Web Worker, akan lebih baik untuk menulis lapisan transport yang akan memberi nomor pada permintaan dan kemudian memastikan operasi ditangani dalam urutan id permintaan.
Roy Tinker
3
-1 Pemrosesan transaksi adalah contoh sempurna di mana Anda harus menggunakan jaminan bahwa barang gagal atau berhasil - hanya karena perintahnya sinkron, tidak berarti bahwa permintaan pertama berhasil ... Anda mengandalkan respons yang memberi tahu Anda seperti itu. Dalam contoh ini Anda akan melakukan permintaan kedua hanya dari dalam handler hasil dari permintaan pertama - dalam hal ini keduanya mungkin juga async.
Mathew
2
@Mathew: itu hanya berlaku jika proses seperti transaksi Anda bergantung pada hasil tindakan sebelumnya. Jika Anda memiliki tombol yang membuat objek baru (diambil dari server) di halaman Anda; jika asinkron, pengguna berpotensi mengklik beberapa kali dan mengembalikan banyak objek. Panggilan sinkron akan mencegahnya dan hanya mengizinkan objek baru lain dibuat setelah yang pertama selesai, terlepas dari apakah itu error, atau tidak. Harap perhatikan kata-katanya, saya membuatnya seperti transaksi dan bukan transaksi dengan sengaja.
vol7ron
8

Saya akan mengatakan bahwa jika Anda mempertimbangkan untuk memblokir browser pengguna saat permintaan selesai dapat diterima, maka pastikan menggunakan permintaan sinkron.

Jika serialisasi permintaan adalah tujuan Anda, maka ini dapat dicapai menggunakan permintaan async, dengan mengaktifkan callback onComplete dari permintaan Anda sebelumnya di baris berikutnya.

hobodave
sumber
1
Hmm, saya akan menambahkan jendela geser untuk itu, jika tidak, pada dasarnya Anda akan kehilangan waktu pulang-pergi untuk setiap permintaan
Stephan Eggermont
8

Ada banyak kasus dunia nyata di mana pemblokiran UI merupakan perilaku yang diinginkan.

Ambil aplikasi dengan beberapa bidang dan beberapa bidang harus divalidasi oleh panggilan xmlhttp ke server jarak jauh yang menyediakan sebagai masukan nilai bidang ini dan nilai bidang lainnya.

Dalam mode sinkron, logikanya sederhana, pemblokiran yang dialami pengguna sangat singkat dan tidak ada masalah.

Dalam mode async, pengguna dapat mengubah nilai bidang lain saat yang awal sedang divalidasi. Perubahan ini akan memicu panggilan xmlhttp lain dengan nilai dari bidang awal yang belum divalidasi. Apa yang terjadi jika validasi awal gagal? Kekacauan murni. Jika mode sinkronisasi tidak digunakan lagi dan dilarang, logika aplikasi menjadi mimpi buruk untuk ditangani. Pada dasarnya aplikasi harus ditulis ulang untuk mengelola kunci (mis. Menonaktifkan item lain selama proses validasi). Kompleksitas kode meningkat pesat. Gagal melakukannya dapat menyebabkan kegagalan logika dan pada akhirnya merusak data.

Pada dasarnya pertanyaannya adalah: apa yang lebih penting, pengalaman UI yang tidak diblokir atau risiko korupsi data? Jawabannya harus tetap pada pengembang aplikasi, bukan W3C.

Alexandre Avrane
sumber
1
Saya pikir Anda menggabungkan gagasan memblokir interaksi pengguna dengan memblokir utas browser. Ada satu miliar cara sederhana untuk mencegah pengguna terus berinteraksi dengan entitas tertentu (bidang formulir, dll) selama panggilan asinkron yang tidak memerlukan pemblokiran untaian browser. Ketika utas diblokir, tidak akan ada pemrosesan logis apa pun, dan itu hanya situasi yang buruk; ia menciptakan jauh lebih banyak masalah / potensi masalah, yang hampir tidak dapat dipecahkan, daripada yang dapat dipecahkan.
Luke Chavers
6

Saya dapat melihat penggunaan permintaan XHR sinkron yang akan digunakan saat sumber daya di lokasi variabel harus dimuat sebelum sumber daya statis lainnya di halaman yang bergantung pada sumber daya pertama untuk berfungsi penuh. Faktanya, saya menerapkan permintaan XHR semacam itu di sub-proyek kecil saya sendiri sedangkan sumber daya JavaScript berada di lokasi variabel di server tergantung pada serangkaian parameter tertentu. Sumber daya JavaScript berikutnya bergantung pada sumber daya variabel tersebut dan file semacam itu HARUS dijamin untuk dimuat sebelum file tepercaya lainnya dimuat, sehingga membuat aplikasi menjadi utuh.

Landasan ide itu benar-benar berkembang pada jawaban vol7ron. Prosedur berbasis transaksi benar-benar satu-satunya waktu di mana permintaan sinkron harus dibuat. Dalam kebanyakan kasus lain, panggilan asinkron adalah alternatif yang lebih baik di mana, setelah panggilan, DOM diperbarui seperlunya. Dalam banyak kasus, seperti sistem berbasis pengguna, Anda mungkin memiliki fitur tertentu yang dikunci untuk "pengguna yang tidak sah" hingga mereka, per se, masuk. Fitur tersebut, setelah panggilan asinkron, dibuka kuncinya melalui prosedur pembaruan DOM.

Saya akhirnya harus mengatakan bahwa saya setuju dengan sebagian besar poin individu tentang masalah ini: sedapat mungkin, permintaan XHR sinkron harus dihindari karena, dengan cara kerjanya, browser terkunci dengan panggilan sinkron. Saat menerapkan permintaan sinkron, permintaan tersebut harus dilakukan dengan cara di mana browser biasanya dikunci, bagaimanapun, katakanlah di bagian HEAD sebelum pemuatan halaman benar-benar terjadi.

hiponiq
sumber
Fakta bahwa suatu tindakan bergantung pada hasil dari tindakan lain bukanlah alasan untuk melakukan tindakan lain tersebut secara sinkron. Hanya jika hasil dari beberapa tindakan harus diproses sebelum fungsi panggilan berakhir, Anda memerlukan panggilan sinkron.
Stijn de Witt
5

Pada 2015 aplikasi javascript desktop menjadi lebih populer. Biasanya dalam aplikasi tersebut saat memuat file lokal (dan memuatnya menggunakan XHR adalah opsi yang benar-benar valid), kecepatan muat sangat cepat sehingga tidak ada gunanya memperumit kode dengan async. Tentu saja mungkin ada kasus di mana asinkron adalah cara yang harus dilakukan (meminta konten dari internet, memuat file yang sangat besar atau sejumlah besar file dalam satu batch), tetapi sebaliknya sinkronisasi berfungsi dengan baik (dan jauh lebih mudah digunakan) .

jahu
sumber
Ini sebenarnya adalah situasi yang saya hadapi dan ini tahun 2020. Saya memiliki aplikasi desktop yang menampilkan UI-nya melalui HTTP sehingga Anda dapat mengaksesnya dari browser yang berjalan di mesin lokal atau bahkan melalui jaringan. Dalam skenario ini, jaringan cepat dan andal, jadi melakukan permintaan XHR sinkron adalah cara terbaik untuk menjaga kode tetap sederhana. Kebanyakan orang tidak menyadari bahwa permintaan XHR asinkron seperti menggunakan utas dan itu bisa menjadi sangat rumit dengan banyak peluang bug.
Eric Mutta
4

jQuery menggunakan AJAX sinkron secara internal dalam beberapa keadaan. Saat memasukkan HTML yang berisi script, browser tidak akan mengeksekusinya. Skrip harus dijalankan secara manual. Skrip ini mungkin melampirkan penangan klik. Asumsikan pengguna mengklik sebuah elemen sebelum handler dipasang dan halaman tidak akan berfungsi sebagaimana mestinya. Oleh karena itu untuk mencegah kondisi balapan, AJAX sinkron akan digunakan untuk mengambil skrip tersebut. Karena AJAX sinkron secara efektif memblokir yang lainnya, dapat dipastikan bahwa skrip dan peristiwa dijalankan dalam urutan yang benar.

Henry
sumber
3

Alasan:

Katakanlah Anda memiliki aplikasi ajax yang perlu melakukan setengah lusin http untuk memuat berbagai data dari server sebelum pengguna dapat melakukan interaksi apa pun.

Jelas Anda ingin ini dipicu dari onload.

Panggilan sinkron berfungsi sangat baik untuk ini tanpa kerumitan tambahan pada kode. Ini sederhana dan lugas.

Kekurangan:

Satu-satunya kelemahan adalah browser Anda terkunci hingga semua data dimuat atau terjadi batas waktu. Adapun aplikasi ajax yang dimaksud, ini tidak terlalu menjadi masalah karena aplikasi tidak berguna sampai semua data awal dimuat.

Alternatif?

Namun banyak browser mengunci semua jendela / tab ketika javascript sibuk di salah satu dari mereka, yang merupakan masalah desain browser yang bodoh - tetapi sebagai akibatnya memblokir pada jaringan yang mungkin lambat menjadi tidak sopan jika mencegah pengguna menggunakan tab lain sambil menunggu halaman ajax dimuat.

Namun, sepertinya sinkronisasi telah dihapus atau dibatasi dari browser terbaru. Saya tidak yakin apakah itu karena seseorang memutuskan bahwa mereka selalu jahat, atau jika penulis browser bingung dengan WC Working Draft tentang topik tersebut.

http://www.w3.org/TR/2012/WD-XMLHttpRequest-20120117/#the-open-method membuatnya tampak seperti (lihat bagian 4.7.3) Anda tidak diizinkan untuk menyetel batas waktu saat menggunakan mode pemblokiran . Tampaknya berlawanan dengan intuisi bagi saya: Setiap kali seseorang memblokir IO, itu sopan untuk menetapkan waktu tunggu yang wajar, jadi mengapa mengizinkan pemblokiran io tetapi tidak dengan waktu tunggu yang ditentukan pengguna?

Pendapat saya, pemblokiran IO memiliki peran penting dalam beberapa situasi tetapi harus dilaksanakan dengan benar. Meskipun tidak dapat diterima untuk satu tab atau jendela browser untuk mengunci semua tab atau jendela lain, itu adalah cacat desain browser. Malu di mana rasa malu itu karena. Tetapi sangat dapat diterima dalam beberapa kasus untuk tab atau jendela individual menjadi non-responsif selama beberapa detik (yaitu menggunakan pemblokiran IO / HTTP GET) dalam beberapa situasi - misalnya, pada pemuatan halaman, mungkin banyak data perlu dilakukan sebelum apa pun bisa dilakukan. Terkadang kode pemblokiran yang diterapkan dengan benar adalah cara terbersih untuk melakukannya.

Tentu saja fungsi yang setara dalam hal ini dapat diperoleh dengan menggunakan http asynchronous, tetapi rutinitas konyol seperti apa yang diperlukan?

Saya kira saya akan mencoba sesuatu seperti ini:

Saat memuat dokumen, lakukan hal berikut: 1: Siapkan 6 variabel flag "Selesai" global, yang diinisialisasi ke 0. 2: Jalankan semua 6 background get (Dengan asumsi urutan tidak menjadi masalah)

Kemudian, callback penyelesaian untuk masing-masing dari 6 http get akan menyetel flag "Selesai" masing-masing. Selain itu, setiap callback akan memeriksa semua flag done lainnya untuk melihat apakah semua 6 HTTP telah selesai. Callback terakhir yang harus diselesaikan, setelah melihat bahwa semua yang lain telah selesai, kemudian akan memanggil fungsi init REAL yang kemudian akan mengatur semuanya, sekarang setelah semua data diambil.

Jika urutan pengambilan penting - atau jika server web tidak dapat menerima beberapa permintaan pada saat yang sama - Anda akan membutuhkan sesuatu seperti ini:

Dalam onload (), http get pertama akan diluncurkan. Dalam callbacknya, yang kedua akan diluncurkan. Dalam callback-nya, yang ketiga - dan seterusnya, dengan setiap callback meluncurkan HTTP GET berikutnya. Ketika yang terakhir kembali, maka itu akan memanggil rutin init () yang sebenarnya.

Jesse Gordon
sumber
2

Apa yang terjadi jika Anda melakukan panggilan sinkron dalam kode produksi?

Langit jatuh.

Tidak serius, pengguna tidak menyukai browser yang terkunci.

martinr
sumber
2
Pertanyaannya adalah "mengapa melakukannya dengan XMLHTTPREQUEST" bukan "mengapa melakukan atau tidak melakukan sinkronisasi panggilan"
Itay Moav -Malimovka
1
Jika Anda menambahkan batas waktu yang wajar, itu seharusnya tidak menjadi masalah.
Greg
1
Dia meminta kasus penggunaan panggilan sinkronisasi ... Bukan untuk kerugiannya (kita semua tahu ini sekarang ...)
Stijn de Witt
pengguna apa? apakah semua pengguna sama? bagaimana dengan teknisi yang menguji secara lokal? ... jadi mengakses file dari sistem file dengan sedikit lag ????
pengguna2800679
2

Saya menggunakannya untuk memvalidasi nama pengguna, selama pemeriksaan bahwa nama pengguna belum ada.

Saya tahu akan lebih baik melakukan itu secara asinkron, tetapi kemudian saya harus menggunakan kode yang berbeda untuk aturan validasi khusus ini. Saya menjelaskan lebih baik. Setup validasi saya menggunakan beberapa fungsi validasi, yang mengembalikan true atau false, tergantung apakah datanya valid.

Karena fungsinya harus kembali, saya tidak bisa menggunakan teknik asynchronous, jadi saya hanya membuat sinkronis itu dan berharap server akan menjawab cukup cepat agar tidak terlalu terlihat. Jika saya menggunakan callback AJAX, maka saya harus menangani sisa eksekusi secara berbeda dari metode validasi lainnya.

Andrea
sumber
Salah satu trik dalam skenario seperti itu adalah membiarkan fungsi validasi hanya memeriksa sebuah bendera (yang dimulai sebagai false) dan hanya menyetelnya ke benar atau salah ketika server merespons. pada pergantian bidang Anda mengatur ulang bendera dan memanggil server lagi.
Stijn de Witt
2

Terkadang Anda memiliki tindakan yang bergantung pada orang lain. Misalnya, tindakan B hanya bisa dimulai jika A sudah selesai. Pendekatan sinkron biasanya digunakan untuk menghindari kondisi balapan . Terkadang menggunakan panggilan sinkron adalah implementasi yang lebih sederhana, lalu membuat logika kompleks untuk memeriksa setiap status panggilan asinkron Anda yang bergantung satu sama lain.

Masalah dengan pendekatan ini adalah Anda "memblokir" browser pengguna hingga tindakan selesai (hingga permintaan kembali, selesai, dimuat, dll). Jadi berhati-hatilah saat menggunakannya.

GmonC
sumber
Pertanyaannya adalah "mengapa melakukannya dengan XMLHTTPREQUEST" bukan "mengapa melakukan sinkronisasi panggilan"
Itay Moav -Malimovka
Penulis sendiri mengatakan " Panggilan sinkron memblokir browser yang mengarah ke pengalaman pengguna yang buruk." dalam sebuah komentar, jadi semua orang di utas ini menerapkan pendekatan "panggilan sinkron". Mengapa Anda mengambil pemahaman literal dari pertanyaan ini jika Anda tidak dapat benar-benar mengatakan dengan pasti apa yang penulis maksudkan?
GmonC
2

Saya menggunakan panggilan sinkron saat mengembangkan kode- apa pun yang Anda lakukan saat permintaan sedang dalam perjalanan ke dan dari server dapat mengaburkan penyebab kesalahan.

Ketika berfungsi, saya membuatnya asynchronous, tetapi saya mencoba memasukkan timer yang dibatalkan dan panggilan balik yang gagal, karena Anda tidak pernah tahu ...

kennebec
sumber
2

SYNC vs ASYNC: Apakah perbedaannya?

Pada dasarnya intinya adalah ini:

console.info('Hello, World!');
doSomething(function handleResult(result) {
    console.info('Got result!');
});
console.info('Goodbye cruel world!');

Ketika doSomethingadalah sinkron ini akan mencetak:

Hello, World!
Got result!
Goodbye cruel world!

Sebaliknya, jika doSomethingadalah asynchronous , ini akan mencetak:

Hello, World!
Goodbye cruel world!
Got result!

Karena fungsinya doSomethingmelakukan pekerjaannya secara asinkron, ia kembali sebelum pekerjaan selesai. Jadi kami hanya mendapatkan hasilnya setelah mencetakGoodbye cruel world!

Jika kita bergantung pada hasil panggilan asynch, kita perlu menempatkan kode tergantung di callback:

console.info('Hello, World!');
doSomething(function handleResult(result) {
    console.info('Got result!');
    if (result === 'good') {
        console.info('I feel great!');
    }
    else {
        console.info('Goodbye cruel world!');
    }
});

Dengan demikian, fakta bahwa 2 atau tiga hal perlu terjadi secara berurutan bukanlah alasan untuk melakukannya secara sinkron (meskipun kode sinkronisasi lebih mudah untuk dikerjakan oleh kebanyakan orang).

MENGAPA MENGGUNAKAN SYNCHRONOUS XMLHTTPREQUEST?

Ada beberapa situasi di mana Anda membutuhkan hasil sebelum fungsi yang dipanggil selesai. Pertimbangkan skenario ini:

function lives(name) {
    return (name !== 'Elvis');
}
console.info('Elvis ' + (lives('Elvis') ? 'lives!' : 'has left the building...');

Misalkan kita tidak memiliki kendali atas kode panggilan ( console.infobaris) dan perlu mengubah fungsi livesuntuk bertanya ke server ... Tidak mungkin kita dapat melakukan permintaan asinkron ke server dari dalam livesdan masih memiliki respons sebelum livesselesai. Jadi kami tidak akan tahu apakah akan kembali trueatau false. Satu-satunya cara untuk mendapatkan hasil sebelum fungsi selesai adalah dengan melakukan permintaan sinkron.

Seperti yang Sami Samhuridisebutkan dalam jawabannya, skenario yang sangat nyata di mana Anda mungkin memerlukan jawaban atas permintaan server Anda sebelum fungsi Anda berakhir adalah onbeforeunloadperistiwa, karena ini adalah fungsi terakhir dari aplikasi Anda yang akan berjalan sebelum jendela ditutup.

SAYA TIDAK PERLU PANGGILAN SINKRONISASI, TETAPI SAYA MENGGUNAKANNYA SEBAGAI MUDAH

Tolong jangan. Panggilan sinkron mengunci browser Anda dan membuat aplikasi terasa tidak responsif. Tapi kamu benar. Kode Async lebih sulit. Namun demikian, ada cara untuk membuatnya lebih mudah. Tidak semudah menyinkronkan kode, tetapi semakin mendekati: Promise s.

Berikut ini contohnya: Dua panggilan asinkron harus diselesaikan dengan sukses sebelum segmen kode ketiga dapat berjalan:

var carRented = rentCar().then(function(car){
  gasStation.refuel(car);
});

var hotelBooked = bookHotel().then(function(reservation) {
  reservation.confirm();
});

Promise.all([carRented, hotelBooked]).then(function(){
  // At this point our car is rented and our hotel booked.
  goOnHoliday();
});

Berikut adalah cara Anda menerapkan bookHotel:

function bookHotel() {
  return new Promise(function(resolve, reject){
    if (roomsAvailable()) {
      var reservation = reserveRoom();
      resolve(reservation);
    }
    else {
      reject(new Error('Could not book a reservation. No rooms available.'));
    }
  });
}

Lihat juga: Menulis JavaScript yang Lebih Baik dengan Janji .

Stijn de Witt
sumber
1
"Mohon jangan. Panggilan sinkron mengunci browser Anda dan membuat aplikasi terasa tidak responsif" Ini tidak selalu menjadi masalah. Bayangkan Anda menguji localhost, dan Anda adalah seorang dev.
pengguna2800679
2

XMLHttpRequestsecara tradisional digunakan untuk permintaan asynchronous. Terkadang (untuk debugging, atau logika bisnis tertentu) Anda ingin mengubah semua / beberapa panggilan asinkron dalam satu halaman untuk disinkronkan.

Anda ingin melakukannya tanpa mengubah semua yang ada di kode JS Anda. Bendera async / sync memberi Anda kemampuan itu, dan jika dirancang dengan benar, Anda hanya perlu mengubah satu baris dalam kode Anda / mengubah nilainya varselama waktu eksekusi.

Itay Moav -Malimovka
sumber
1

Firefox (dan kemungkinan semua browser non-IE) tidak mendukung timeOut XHR asinkron.

  1. Diskusi Stackoverflow
  2. Mozilla Firefox XMLHttpRequest

HTML5 WebWorkers mendukung waktu tunggu. Jadi, Anda mungkin ingin menggabungkan permintaan XHR sinkronisasi ke WebWorker dengan waktu tunggu untuk mengimplementasikan XHR seperti asinkron dengan perilaku waktu tunggu.

Dmitry Kaigorodov
sumber
1

Saya baru saja mengalami situasi di mana permintaan asinkron untuk daftar url yang dipanggil berturut-turut menggunakan forEach (dan perulangan for) akan menyebabkan permintaan yang tersisa dibatalkan. Saya beralih ke sinkron dan berfungsi sebagaimana mestinya.

AD Regan
sumber
1

Menggunakan permintaan HTTP sinkron adalah praktik umum dalam bisnis periklanan seluler.

Perusahaan (alias "Penerbit") yang membuat aplikasi sering kali menjalankan iklan untuk menghasilkan pendapatan. Untuk ini, mereka memasang SDK iklan ke dalam aplikasi mereka. Banyak yang ada (MoPub, Ogury, TapJob, AppNext, Google Ads AdMob).

SDK ini akan menayangkan iklan dalam tampilan web.

Saat menayangkan iklan kepada pengguna, itu harus menjadi pengalaman yang lancar , terutama saat memutar video. Seharusnya tidak ada buffering atau pemuatan setiap saat.

Untuk mengatasi ini precaching digunakan. Dimana media (gambar / video / dll) dimuat secara sinkron di latar belakang tampilan web.

Mengapa tidak melakukannya secara asinkron?

  1. Ini adalah bagian dari standar yang diterima secara global
  2. SDK mendengarkan onloadperistiwa tersebut untuk mengetahui kapan iklan "siap" untuk ditayangkan kepada pengguna

Dengan penghentian XMLHttpRequests sinkron , bisnis iklan kemungkinan besar akan dipaksa untuk mengubah standar di masa mendatang kecuali cara lain dapat ditentukan.

kemicofa ghost
sumber
0

Synchronous XHR bisa sangat berguna untuk alat internal (non-produksi) dan / atau pengembangan kerangka kerja. Bayangkan, misalnya, Anda ingin memuat pustaka kode secara sinkron pada akses pertama, seperti ini:

get draw() 
{
    if (!_draw)
    {
       let file;
       switch(config.option)
       {
           case 'svg':
              file = 'svgdraw.js';
              break;
           case 'canvas':
              file = 'canvasdraw.js';
              break;
           default:
              file = 'webgldraw.js';
       }

       var request = new XMLHttpRequest();
       request.open('GET', file, false);
       request.send(null);
       _draw = eval(request.responseText);
    }

    return _draw;
}

Sebelum Anda menjadi bingung dan secara membabi buta memuntahkan eval dari kejahatan, perlu diingat bahwa ini hanya untuk pengujian lokal. Untuk build produksi, _draw sudah disetel.

Jadi, kode Anda mungkin terlihat seperti ini:

foo.drawLib.draw.something(); //loaded on demand

Ini hanyalah satu contoh dari sesuatu yang tidak mungkin dilakukan tanpa sinkronisasi XHR. Anda dapat memuat pustaka ini di awal, ya, atau melakukan janji / panggilan balik, tetapi Anda tidak dapat memuat lib secara sinkron tanpa sinkronisasi XHR. Pikirkan tentang seberapa banyak hal semacam ini dapat membersihkan kode Anda ...

Batasan untuk apa yang dapat Anda lakukan dengan ini untuk perkakas dan kerangka kerja (berjalan secara lokal) hanya dibatasi oleh imajinasi Anda. Padahal, tampaknya imajinasi agak terbatas di dunia JavaScript.

pengguna2800679
sumber
-1

Nah, inilah satu alasan bagus. Saya ingin melakukan permintaan http, tergantung pada hasilnya, panggil click () pada input type = file. Ini tidak mungkin dengan xhr atau fetch asinkron. Callback kehilangan konteks "tindakan pengguna", sehingga panggilan click () diabaikan. Xhr sinkron menyimpan bacon saya.

onclick(event){
    //here I can, but I don't want to.
    //document.getElementById("myFileInput").click();
    fetch("Validate.aspx", { method : "POST", body: formData, credentials: "include" })
    .then((response)=>response.json())
    .then(function (validResult) {
        if (validResult.success) {
            //here, I can't.
            document.getElementById("myFileInput").click();
        }
    });
}
bbsimonbb
sumber
simpan di var
Es Noguera