JavaScript 回调中的控制反转:为什么 Promise 是答案

WBOY
发布: 2024-08-09 06:33:02
原创
617 人浏览过

回调函数是作为参数传递给另一个函数的函数,然后在外部函数内部调用该函数以完成某种例程或操作。可以通过两种方式调用回调:同步和异步。这是 Javascript 中最基本的异步模式。

例如:

Inversion of Control in JavaScript Callbacks: Why Promises are the Answer

AB现在发生,在主JS程序的直接控制下。但是 C 被推迟到稍后发生,并在另一方的控制下,在本例中是 ajax(..) 函数。从基本意义上来说,这种控制权的交接通常不会给程序带来很多问题。

但是,频率不高并不足以忽视问题或问题。事实上,这是回调驱动设计的主要问题之一。它围绕着这样一个想法:有时 ajax(..) 或您传递回调延续的“一方”不是您编写的函数,也不是您直接控制的函数。很多时候它是一些第三方提供的实用程序。

当您参与程序并将其执行控制权交给另一个第三方时,我们称之为“控制反转”。您的代码和第三方实用程序之间存在一个不言而喻的“合同”——您希望维护的一组内容。

“控制反转”有什么问题?

有一个例子可以更好地理解这个问题。

假设您正在为您的公司建立一个旅行预订网站。您添加了一个使用第三方库的 createBooking() 函数的“立即预订”按钮。此函数处理预订,然后调用您的回调以向客户发送确认电子邮件。

这段代码可能看起来像:

Inversion of Control in JavaScript Callbacks: Why Promises are the Answer

测试期间一切正常。人们开始在您的网站上预订旅行套餐,每个人都对您的工作感到满意。突然有一天,你接到老板打来的电话,询问一个重大问题。一位顾客预订了套餐,一次预订收到了四封相同的确认电子邮件。

您开始调试问题。您查看发送确认电子邮件的代码部分,一切似乎都是正确的。然后,您进一步调查,发现第三方库中的 createBooking() 实用程序调用了您的回调函数四次,导致发送了四封确认电子邮件。

您联系第三方图书馆的支持团队并说明情况。他们告诉您,他们以前从未遇到过这个问题,但会优先考虑该问题并回复您。一天后,他们会给您回电话并告知他们的调查结果。他们发现一段不应该上线的实验性代码导致 createBooking() 函数多次调用回调。

问题是在他们这边,他们向你保证它已经解决了。他们对造成的麻烦表示歉意,并确认该问题不会再次发生。

为了防止在寻求解决方案后出现任何不需要的问题,您可以实现一个简单的 if 语句,如下所示,团队对此似乎很满意:

Inversion of Control in JavaScript Callbacks: Why Promises are the Answer

但是随后一位 QA 工程师问道:“如果他们从不调用回调会发生什么?”哎呀。你们都没有想过这一点!

您开始考虑他们调用您的回调可能出现的所有问题。以下是一些问题的列表:

  • 过早调用回调

  • 调用回调太晚了(或根本不调用)

  • 调用回调的次数太少或太多(如上例中的问题)

  • 吞下任何可能发生的错误/异常

  • ...

您可能会意识到,您必须在代码中针对不同情况实现许多解决方案,这将使代码变得糟糕且肮脏,因为传递给实用程序的每个回调都需要它。

承诺

如果我们能够反转控制反转会怎样?如果我们不是将程序的延续传递给另一方,而是期望它返回给我们一种能力,让我们知道其任务何时完成,然后我们的代码可以决定下一步做什么?

Promises menawarkan cara yang berkuasa untuk mengendalikan operasi tak segerak dalam JavaScript, menangani isu seperti neraka panggil balik dan penyongsangan kawalan. Tidak seperti panggilan balik, Promises membolehkan anda mengurus tugas tak segerak tanpa melepaskan kawalan kod anda.

Pertimbangkan untuk memesan burger keju di restoran makanan segera. Anda menerima resit, janji burger keju masa depan anda. Semasa anda menunggu, anda boleh melakukan perkara lain, mengetahui anda akan mendapat pesanan anda akhirnya. Begitu juga, Janji dalam JavaScript mewakili nilai masa hadapan, membolehkan kod anda berjalan dengan lancar.

Janji juga menangani kegagalan dengan anggun, sama seperti anda mungkin dimaklumkan jika restoran kehabisan burger keju. Struktur ini menjadikan kod anda lebih mudah dibaca dan diselenggara.

Saya tidak akan membincangkan Promises secara mendalam di sini, tetapi dengan menggunakannya, anda boleh menulis kod tak segerak yang lebih bersih dan boleh dipercayai, meningkatkan kualiti keseluruhan aplikasi JavaScript anda.

Sebagai contoh, untuk laman web tempahan perjalanan yang kami nyatakan sebelum ini, jika utiliti pihak ketiga mengembalikan janji, kami boleh menanganinya seperti ini:

Inversion of Control in JavaScript Callbacks: Why Promises are the Answer

Setelah Janji diselesaikan (berjaya disempurnakan), ia kekal seperti itu selama-lamanya — ia menjadi nilai yang tidak berubah pada ketika itu dan kemudiannya boleh dipatuhi seberapa banyak yang perlu. Ini bermakna janji yang diselesaikan, nilai yang diselesaikan boleh diakses atau digunakan beberapa kali dalam kod anda tanpa menjejaskan keadaannya. Ini membolehkan anda mengendalikan hasil operasi tak segerak dalam pelbagai bahagian aplikasi anda tanpa perlu risau tentang Janji berubah atau dinilai semula.

Janji ialah penyelesaian untuk penyongsangan isu kawalan yang berlaku dalam kod panggil balik sahaja. Panggilan balik mewakili penyongsangan kawalan. Jadi penyongsangan corak panggil balik sebenarnya adalah penyongsangan penyongsangan, atau penyongsangan kawalan. Memulihkan kawalan kembali kepada kod panggilan yang kami mahukan berada di tempat pertama.

Rujukan

  • Anda Tidak Tahu JS: Async & Performance oleh Kyle Simpson

  • developer.mozilla.org

以上是JavaScript 回调中的控制反转:为什么 Promise 是答案的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:dev.to
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责声明 Sitemap
PHP中文网:公益在线PHP培训,帮助PHP学习者快速成长!