cari
Rumahhujung hadapan webtutorial jsPenjelasan terperinci tentang Promises asynchronous issues_javascript kemahiran

Sekarang, mungkin setiap pembangun JavaScript dan nenek mereka pernah mendengar tentang Janji. Jika anda belum, anda akan melakukannya. Konsep janji telah dicadangkan oleh ahli pasukan CommonJS dalam spesifikasi Promises/A. Janji semakin digunakan sebagai cara untuk mengurus panggilan balik untuk operasi tak segerak, tetapi dengan reka bentuk mereka jauh lebih berguna daripada itu. Malah, disebabkan pelbagai kegunaannya, ramai orang telah memberitahu saya - selepas saya menulis sesuatu tentang janji - bahawa saya "hilang titik" janji. Jadi apa gunanya janji?

Sesuatu tentang Janji

Sebelum saya masuk ke dalam "seri-seri" janji, saya fikir saya akan memberi anda sedikit pandangan dalaman tentang cara ia berfungsi. Janji ialah objek yang—mengikut spesifikasi Promise/A—hanya memerlukan satu kaedah: kemudian. Kaedah kemudian mengambil tiga parameter: panggilan balik kejayaan, panggilan balik kegagalan dan panggilan balik ke hadapan (spesifikasi tidak memerlukan pelaksanaan panggilan balik ke hadapan untuk disertakan, tetapi banyak yang melakukannya). Objek janji baharu dikembalikan daripada setiap panggilan kemudian.
Janji boleh berada dalam salah satu daripada tiga keadaan: tidak ditepati, selesai atau gagal. Janji bermula dalam keadaan tidak ditepati Jika berjaya ia akan disempurnakan, jika ia gagal ia akan gagal. Apabila janji berpindah ke keadaan siap, semua panggilan balik kejayaan yang didaftarkan untuknya akan dipanggil dan nilai hasil kejayaan akan dihantar kepadanya. Di samping itu, sebarang panggilan balik kejayaan yang didaftarkan pada janji akan dipanggil serta-merta selepas ia selesai.

Perkara yang sama berlaku apabila janji berpindah ke keadaan gagal, kecuali ia memanggil panggilan balik kegagalan dan bukannya panggilan balik kejayaan. Untuk pelaksanaan yang termasuk ciri kemajuan, janji boleh mengemas kini kemajuannya pada bila-bila masa sebelum ia meninggalkan keadaan yang tidak dipenuhi. Apabila kemajuan dikemas kini, semua panggilan balik kemajuan diberikan nilai kemajuan dan dipanggil serta-merta. Panggilan balik kemajuan dikendalikan secara berbeza daripada panggilan balik kejayaan dan kegagalan jika anda mendaftarkan panggilan balik kemajuan selepas kemas kini kemajuan berlaku, panggilan balik kemajuan baharu hanya akan dipanggil untuk kemajuan yang dikemas kini selepas ia didaftarkan.
Kami tidak akan pergi lebih jauh tentang bagaimana keadaan janji diurus kerana itu di luar spesifikasi dan setiap pelaksanaan berbeza. Dalam contoh kemudian anda akan melihat bagaimana ia dilakukan, tetapi buat masa ini itu sahaja yang anda perlu tahu.

Mengendalikan panggilan balik

Mengendalikan panggilan balik untuk operasi tak segerak seperti yang dinyatakan sebelum ini ialah penggunaan janji yang paling asas dan biasa Mari kita bandingkan panggilan balik standard dengan panggilan balik menggunakan janji.

// Normal callback usage
asyncOperation(function() {
  // Here's your callback
});
// Now `asyncOperation` returns a promise
asyncOperation().then(function(){
  // Here's your callback
});

Saya ragu sesiapa akan benar-benar mengambil berat untuk menggunakan janji hanya dengan melihat contoh ini. Nampaknya tiada faedah, kecuali "kemudian" menjadikannya lebih jelas bahawa fungsi panggil balik dipanggil selepas operasi tak segerak selesai. Tetapi walaupun dengan faedah ini, kami kini mempunyai lebih banyak kod (abstraksi sepatutnya menjadikan kod kami lebih pendek, bukan?) dan janji adalah kurang berprestasi daripada panggilan balik standard.

Tetapi jangan biarkan ini menghalang anda. Jika ini adalah yang terbaik yang boleh dilakukan oleh janji, artikel ini tidak akan wujud

Piramid Azab

// Normal callback usage => PYRAMID OF DOOOOOOOOM
asyncOperation(function(data){
  // Do some processing with `data`
  anotherAsync(function(data2){
    // Some more processing with `data2`
    yetAnotherAsync(function(){
      // Yay we're finished!
    });
  });
});
// Let's look at using promises
asyncOperation()
.then(function(data){
  // Do some processing with `data`
  return anotherAsync();
})
.then(function(data2){
  // Some more processing with `data2`
  return yetAnotherAsync();
})
.then(function(){
  // Yay we're finished!
});

正如你所见,promises的使用使得事情变扁平而且更可读了。这能起作用是因为——像早先提到的——then返回了一个promise,所以你可以将then的调用不停的串连起来。由then返回的promise装载了由调用返回的值。如果调用返回了一个promise(像这个例子中的情形一样),then返回的 promise装载了与你的回调返回的promise所装载的相同值。这内容很多,因此我将帮助你一步一步的理解它

异步操作返回一个promise对象。因此我们在那个promise对象中调用then,并且传给它一个回调函数;then也会返回一个promise。当异步操作结束,它将给promise装上数据。然后(第一次)回调被调用,数据被作为参数传递进去。如果回调不含有返回值,then返回的promise将会立即不带值组装。如果回调返回的不是一个promise,那么then返回的 promise将会立即装载那个数值。如果回调返回一个promise(像例子中的),那么then返回的 promise将等待直到我们回调返回的promise被完全装载。一旦我们回调的 promise被装载,它装载的值(本例中就是data2)将会被提交给then的promise。然后then中的promise装载了data2。等等。听起来有点复杂,但事实上很简单,如果我说的你不能理解,我非常抱歉。我猜我可能不是谈论它的最佳人选。

用命名的回调替代

但显然 promises 不是使这个结构扁平化的唯一方法。在写了一篇提到promises解决了厄运的金字塔问题的帖子之后,有个人对该帖评论说……

我想promises有时是有用的,但是“嵌套”的回调的问题(圣诞树综合症)可以仅用一个命名的函数作为一个参数替代匿名函数的方法平常的处理:

asyncCall( param1, param2, HandlerCallback );
function HandlerCallback(err, res){
// do stuff
}

它的例子只是给出了一层深的例子,但它仍是正确的。我们来扩展我前面的例子,使这个看起来容易些。

命名回调

// Normal callback usage => PYRAMID OF DOOOOOOOOM
asyncOperation(handler1);
function handler1(data) {
  // Do some processing with `data`
  anotherAsync(handler2);
}
function handler2(data2) {
  // Some more processing with `data2`
  yetAnotherAsync(handler3);
}
function handler3() {
  // Yay we're finished!
}

看看上面的代码!他们绝对是对的!它就是一个扁平的结构,但是这里有个问题同样也存在于 我以前从来没有注意过的老的回调例子中:依赖性和复用性。依赖性和复用性是相互关联的可逆类型。一样东西依赖的越少,那么它的复用性就越大。在以上的例子中,handler1依赖handler2,handler2依赖handler3.这就意味着handler1无论出于任何目的都不可在被用除非handler2也呈现出来。假如你不打算重用他们,那么给你的函数命名又有什么意义呢?

最糟糕的的是handler1都不关心在handler2里面发生了什么事情。它压根就不需要handler2除了和它异步工作。因此,让我们消除这些依赖性然后通过用promise使函数更具复用性。

链式回调

asyncOperation().then(handler1).then(handler2).then(handler3);
function handler1(data) {
  // Do some processing with `data`
  return anotherAsync();
}
function handler2(data2) {
  // Some more processing with `data2`
  return yetAnotherAsync();
}
function handler3() {
  // Yay we're finished!
}

这样看起来是不是好多了?假如另外的函数存在的话,现在handler1和handler2都互不相关了。想看看他们是否真的很棒呢?现在handler1可以被用在不需要handler2的情况下了。相反,handler1被操作以后,我们将可以用另一个handler。

复用函数

asyncOperation().then(handler1).then(anotherHandler);
function handler1(data) {
  // Do some processing with `data`
  return anotherAsync();
}
function anotherHandler(data2) {
  // Do some really awesome stuff that you've never seen before. It'll impress you
}

现在handler1已经从handler2脱离而且可以被用在了更多的情形中,特别是那些由handler2提供的功能而我们又不想用的。这就是复用性!评论家解决代码易读性的唯一方法就是通过消除缩进。我们不想消除缩进仅仅是为了缩进。多层次的缩进仅仅是某些事情错误的标志,问题不一定在它本身。他就像是由脱水引起的头痛。真正的问题是脱水,不是头痛。解决的方法是获得水合物,而不是用一些止痛药。

并行异步操作

在前面我提到的文章里,我将promises与events在处理异步操作方面做了比较。遗憾的是,按照那些曾提到过的人在评论里给的说法,我比较的不是很成功。我描述出了promises的力量,接着转到events来描述它们的力量,就像在我的特别项目里用到的那样。没有比较和对比。一位评论者写道(修改了一点语法错误):

我想用帖子中的例子是一个坏的对照。有篇论文证明了promises的值将会怎样,如果按下虚构的“启动服务器按钮”,将不仅仅是启动一个web服务器,还有一个数据库服务器,当它们都在运行的时候只是更新了UI。

使用promise的.when方法将会使这种“多个异步操作”例子变得普通,然而响应多个异步事件需要一个并不普通的代码量。
他完全正确。事实上我没有比较那两种情况。那篇文章的要点实际在于说明promises不是异步操作的唯一机制,而且在一些情况下,它们也不一定是最好的。在这个评论者指出的情况下,promises当然是最佳的解决办法。我们来看看他说的是什么

jQuery 具有 一个名为when的方法 ,可以带上任意数量的promise参数,并返回一个单一的promise。如果任何一个promise传入失败,when返回的promise也会失败。如果所有的promises被装载,那么每个值都将会按照promises被定义的顺序传递给附加的回调。

以并行的方式执行无数的异步操作非常有用,然后只要在它们之中的每一个结束之后继续执行回调。我们看一个简单的例子。

jQuery.when

// Each of these async functions return a promise
var promise1 = asyncOperation1();
var promise2 = asyncOperation2();
var promise3 = asyncOperation3();
// The $ refers to jQuery
$.when(promise1, promise2, promise3).then(
  function(value1, value2, value3){
    // Do something with each of the returned values
  }
);

Les gens disent souvent que c’est l’une des meilleures choses à propos des promesses, et cela fait partie de ce qui rend les promesses importantes. Je pense également que c'est une bonne fonctionnalité qui simplifie beaucoup d'opérations, mais le mécanisme de cette méthode n'est mentionné dans aucune spécification de Promises, donc je ne pense pas que ce soit le but de Promises. Il existe une spécification qui mentionne la méthode when, mais elle est complètement différente de celle ci-dessus. Autant que je sache, jQuery est la seule bibliothèque qui implémente cette méthode when. D'autres bibliothèques de promesses, telles que Q, Dojo et when implémentent la méthode when selon la spécification Promises/B, mais n'implémentent pas la méthode when mentionnée par le commentateur. Cependant, la bibliothèque Q a une méthode all, et when.js a également une méthode parallèle, qui fonctionne de la même manière que la méthode jQuery.when ci-dessus, sauf qu'elle accepte un paramètre de type tableau au lieu d'un nombre arbitraire de paramètres.

Représentation de la valeur

La promesse est une meilleure façon de gérer les scénarios suivants :

"Je souhaite trouver un utilisateur dans cette base de données, mais la méthode de recherche est asynchrone."

Nous avons donc ici une méthode de recherche qui ne peut pas renvoyer une valeur immédiatement. Mais en fin de compte, il "renvoie" une valeur (via un rappel) et vous souhaitez gérer cette valeur d'une manière ou d'une autre. Désormais, en utilisant un rappel, vous pouvez définir une continuation, ou "un code qui gérera cette valeur ultérieurement"

La promesse modifie le "hé, voici un code que vous utiliserez pour gérer les valeurs de retour". Ce sont des méthodes qui permettent à la méthode "find" de dire "Hé, je vais être occupé à chercher les informations que vous recherchez, mais en attendant, vous pouvez continuer à attendre que le résultat vous soit renvoyé, et vous pouvez le traiter comme vous le souhaitez en même temps, comme de vrais trucs »

La promesse représente une vraie valeur. C'est ça le piège. Ils fonctionnent lorsque vous gérez les promesses comme de vraies choses. L'implémentation JavaScript de Promise s'attend à ce que vous lui transmettiez une fonction de rappel. Ce n'est qu'une "coïncidence", ce n'est pas une chose importante.

Je crois que c’est vraiment le but des promesses. Pourquoi? Lisez la première phrase de la spécification Promise/A : « Une promesse représente la valeur renvoyée par l'achèvement d'une opération. » C'est un peu évident, n'est-ce pas ? Eh bien, même si c'est le but, cela ne m'empêche pas de présenter les idées d'autres personnes plus loin dans cet article. Quoi qu’il en soit, parlons un peu plus de cette idée.

Conclusion

Le but d'une promesse est qu'elle représente la valeur du résultat final renvoyé par une opération, mais la raison de leur utilisation est de rendre les opérations synchrones mieux parallèles. Depuis que la programmation asynchrone est entrée en scène, des rappels sont apparus partout, obscurcissant notre code de manière étrange. La promesse est un moyen de le changer. Les promesses nous permettent d'écrire du code de manière synchrone tout en nous donnant une exécution asynchrone du code.

Kenyataan
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
JavaScript dan Web: Fungsi teras dan kes penggunaanJavaScript dan Web: Fungsi teras dan kes penggunaanApr 18, 2025 am 12:19 AM

Penggunaan utama JavaScript dalam pembangunan web termasuk interaksi klien, pengesahan bentuk dan komunikasi tak segerak. 1) kemas kini kandungan dinamik dan interaksi pengguna melalui operasi DOM; 2) pengesahan pelanggan dijalankan sebelum pengguna mengemukakan data untuk meningkatkan pengalaman pengguna; 3) Komunikasi yang tidak bersesuaian dengan pelayan dicapai melalui teknologi Ajax.

Memahami Enjin JavaScript: Butiran PelaksanaanMemahami Enjin JavaScript: Butiran PelaksanaanApr 17, 2025 am 12:05 AM

Memahami bagaimana enjin JavaScript berfungsi secara dalaman adalah penting kepada pemaju kerana ia membantu menulis kod yang lebih cekap dan memahami kesesakan prestasi dan strategi pengoptimuman. 1) aliran kerja enjin termasuk tiga peringkat: parsing, penyusun dan pelaksanaan; 2) Semasa proses pelaksanaan, enjin akan melakukan pengoptimuman dinamik, seperti cache dalam talian dan kelas tersembunyi; 3) Amalan terbaik termasuk mengelakkan pembolehubah global, mengoptimumkan gelung, menggunakan const dan membiarkan, dan mengelakkan penggunaan penutupan yang berlebihan.

Python vs JavaScript: Keluk Pembelajaran dan Kemudahan PenggunaanPython vs JavaScript: Keluk Pembelajaran dan Kemudahan PenggunaanApr 16, 2025 am 12:12 AM

Python lebih sesuai untuk pemula, dengan lengkung pembelajaran yang lancar dan sintaks ringkas; JavaScript sesuai untuk pembangunan front-end, dengan lengkung pembelajaran yang curam dan sintaks yang fleksibel. 1. Sintaks Python adalah intuitif dan sesuai untuk sains data dan pembangunan back-end. 2. JavaScript adalah fleksibel dan digunakan secara meluas dalam pengaturcaraan depan dan pelayan.

Python vs JavaScript: Komuniti, Perpustakaan, dan SumberPython vs JavaScript: Komuniti, Perpustakaan, dan SumberApr 15, 2025 am 12:16 AM

Python dan JavaScript mempunyai kelebihan dan kekurangan mereka sendiri dari segi komuniti, perpustakaan dan sumber. 1) Komuniti Python mesra dan sesuai untuk pemula, tetapi sumber pembangunan depan tidak kaya dengan JavaScript. 2) Python berkuasa dalam bidang sains data dan perpustakaan pembelajaran mesin, sementara JavaScript lebih baik dalam perpustakaan pembangunan dan kerangka pembangunan depan. 3) Kedua -duanya mempunyai sumber pembelajaran yang kaya, tetapi Python sesuai untuk memulakan dengan dokumen rasmi, sementara JavaScript lebih baik dengan MDNWebDocs. Pilihan harus berdasarkan keperluan projek dan kepentingan peribadi.

Dari C/C ke JavaScript: Bagaimana semuanya berfungsiDari C/C ke JavaScript: Bagaimana semuanya berfungsiApr 14, 2025 am 12:05 AM

Peralihan dari C/C ke JavaScript memerlukan menyesuaikan diri dengan menaip dinamik, pengumpulan sampah dan pengaturcaraan asynchronous. 1) C/C adalah bahasa yang ditaip secara statik yang memerlukan pengurusan memori manual, manakala JavaScript ditaip secara dinamik dan pengumpulan sampah diproses secara automatik. 2) C/C perlu dikumpulkan ke dalam kod mesin, manakala JavaScript adalah bahasa yang ditafsirkan. 3) JavaScript memperkenalkan konsep seperti penutupan, rantaian prototaip dan janji, yang meningkatkan keupayaan pengaturcaraan fleksibiliti dan asynchronous.

Enjin JavaScript: Membandingkan PelaksanaanEnjin JavaScript: Membandingkan PelaksanaanApr 13, 2025 am 12:05 AM

Enjin JavaScript yang berbeza mempunyai kesan yang berbeza apabila menguraikan dan melaksanakan kod JavaScript, kerana prinsip pelaksanaan dan strategi pengoptimuman setiap enjin berbeza. 1. Analisis leksikal: Menukar kod sumber ke dalam unit leksikal. 2. Analisis Tatabahasa: Menjana pokok sintaks abstrak. 3. Pengoptimuman dan Penyusunan: Menjana kod mesin melalui pengkompil JIT. 4. Jalankan: Jalankan kod mesin. Enjin V8 mengoptimumkan melalui kompilasi segera dan kelas tersembunyi, Spidermonkey menggunakan sistem kesimpulan jenis, menghasilkan prestasi prestasi yang berbeza pada kod yang sama.

Beyond the Browser: JavaScript di dunia nyataBeyond the Browser: JavaScript di dunia nyataApr 12, 2025 am 12:06 AM

Aplikasi JavaScript di dunia nyata termasuk pengaturcaraan sisi pelayan, pembangunan aplikasi mudah alih dan Internet of Things Control: 1. Pengaturcaraan sisi pelayan direalisasikan melalui node.js, sesuai untuk pemprosesan permintaan serentak yang tinggi. 2. Pembangunan aplikasi mudah alih dijalankan melalui reaktnatif dan menyokong penggunaan silang platform. 3. Digunakan untuk kawalan peranti IoT melalui Perpustakaan Johnny-Five, sesuai untuk interaksi perkakasan.

Membina aplikasi SaaS Multi-penyewa dengan Next.js (Integrasi Backend)Membina aplikasi SaaS Multi-penyewa dengan Next.js (Integrasi Backend)Apr 11, 2025 am 08:23 AM

Saya membina aplikasi SaaS multi-penyewa berfungsi (aplikasi edTech) dengan alat teknologi harian anda dan anda boleh melakukan perkara yang sama. Pertama, apakah aplikasi SaaS multi-penyewa? Aplikasi SaaS Multi-penyewa membolehkan anda melayani beberapa pelanggan dari Sing

See all articles

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

AI Hentai Generator

AI Hentai Generator

Menjana ai hentai secara percuma.

Artikel Panas

R.E.P.O. Kristal tenaga dijelaskan dan apa yang mereka lakukan (kristal kuning)
1 bulan yang laluBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Tetapan grafik terbaik
1 bulan yang laluBy尊渡假赌尊渡假赌尊渡假赌
Akan R.E.P.O. Ada Crossplay?
1 bulan yang laluBy尊渡假赌尊渡假赌尊渡假赌

Alat panas

Versi Mac WebStorm

Versi Mac WebStorm

Alat pembangunan JavaScript yang berguna

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

Muat turun versi mac editor Atom

Muat turun versi mac editor Atom

Editor sumber terbuka yang paling popular

DVWA

DVWA

Damn Vulnerable Web App (DVWA) ialah aplikasi web PHP/MySQL yang sangat terdedah. Matlamat utamanya adalah untuk menjadi bantuan bagi profesional keselamatan untuk menguji kemahiran dan alatan mereka dalam persekitaran undang-undang, untuk membantu pembangun web lebih memahami proses mengamankan aplikasi web, dan untuk membantu guru/pelajar mengajar/belajar dalam persekitaran bilik darjah Aplikasi web keselamatan. Matlamat DVWA adalah untuk mempraktikkan beberapa kelemahan web yang paling biasa melalui antara muka yang mudah dan mudah, dengan pelbagai tahap kesukaran. Sila ambil perhatian bahawa perisian ini

Pelayar Peperiksaan Selamat

Pelayar Peperiksaan Selamat

Pelayar Peperiksaan Selamat ialah persekitaran pelayar selamat untuk mengambil peperiksaan dalam talian dengan selamat. Perisian ini menukar mana-mana komputer menjadi stesen kerja yang selamat. Ia mengawal akses kepada mana-mana utiliti dan menghalang pelajar daripada menggunakan sumber yang tidak dibenarkan.