And when I promise something, I never ever break that promise. Never.” ― Rapunzel 许多的语言,为了将异步模式处理得更像平常的顺序,都包含一种有趣的方案库,它们被称之为promises,deferreds,或者futures。JavaScript的promises ,可以促进关注点分离,以代替紧密耦合的接口。 本文讲的是基于Promises/A 标准的JavaScript promises。[http://wiki.commonjs.org/wiki/Promises/A] Promise的用例:
JavaScript promise是一个承诺将在未来返回值的对象。是具有良好定义的行为的数据对象。promise有三种可能的状态:
|
郭振华oo
|
一个已经拒绝或者完成的承诺属于已经解决的。一个承诺只能从待定状态变成已经解决的状态。之后,承诺的状态就不变了。承诺可以在它对应的处理完成之后很久还存在。也就是说,我们可以多次取得处理结果。我们通过调用promise.then()来取得结果,这个函数一直到承诺对应的处理结束才会返回。我们可以灵活的串联起一堆承诺。这些串联起来的“then”函数应该返回一个新的承诺或者最早的那个承诺。
为什么要这么麻烦?只用基本的回调函数不行吗? |
f4f
|
回调函数的问题回调函数适合简单的重复性事件,例如根据点击来让一个表单有效,或者保存一个REST调用的结果。回调函数还会使代码形成一个链,一个回调函数调用一个REST函数,并为REST函数设置一个新的回调函数,这个新的回调函数再调用另一个REST函数,依此类推。这就形成了一个如图1中的毁灭金字塔。代码的横向增长大于纵向的增长。回调函数看起来很简单,直到我们需要一个结果,而且是立刻就要,马上就用在下一行的计算中。
|
f4f
|
在图1中,我使用timeout来模拟异步操作。管理异常的方法是痛苦的,很容易玩漏下游的行为。当我们编写回调,那么代码组织变得混乱。图2显示了一个模拟验证流可以运行在NodeJS REPL。在下一节,我们将从pyramid-of-doom模式迁移到一个连续的promise。
在NodeJS REPL执行的结果
|
多多de棉花糖
|
我曾经遇到一个AngularJS动态验证的情况,根据对应表的值,动态的限制表单项的值。限制项的有效值范围被定义在REST服务上。 我写了一个调度器,根据请求的值,去操作函数栈,以避免回调嵌套。调度器从栈中弹出函数并执行。函数的回调会在结束时重新调用调度器,直到栈被清空。每次回调都记录所有从远程验证调用返回的验证错误。 我认为我写的玩意儿是一种反模式。如果我用Angular的$http调用提供的promise,在整个验证过程中我的思维会更近似线性形式,就像同步编程。平展的promise链是可读的。继续... |
郭振华oo
|
使用Promises图3显示了我将验证改写成promise链的样子。其中采用了kew promise库。Q库同样适用。要使用该库,首先使用npm将kew库导入到NodeJS,然后加载代码到NodeJS REPL。
输出和使用嵌套回调时相同:
该代码稍微“长高”了,但我认为更易于理解和修改。更易于加上适当的错误处理。在链的末尾调用fail用于捕获链中错误,但我也可以在任何一个then里面提供一个reject的处理函数做相应的处理。 |
郭振华oo
|
图6显示了一个代码片段,让十个并行的promises每个都包含一个文字promise。只有当十个子类通过或如果任何子类拒绝,最后的then方法才能完成。
下面的地址, http://jsfiddle.net/mauget/XKCy2/,针对JSFiddle在浏览器中运行十个并行promises,随机的拒绝或通过。这里有完整的代码用于检查和变化if条件。重新运行,直到你得到一个相反的完成。图7显示了积极的结果。 图7:JSFiddle并行promises样例 |
多多de棉花糖
|
孕育 Promise许多api返回的promise都有一个then函数——他们是thenable。通常我只是通过then处理thenable函数的结果。然而,$q,mpromise,和kew库拥有同样的API用于创建,拒绝,或者通过promise。这里有API文档链接到每个库的引用部分。我通常不需要构造一个promise,除了本文中的包装promise的未知描述和timeout函数。请参考哪些我创建的promises。 |
多多de棉花糖
|
Promise库互操作大多数JavaScript promise库在then级别进行互操作。你可以从一个外部的promise创建一个promise,因为promise可以包装任何类型的值。then可以支持跨库工作。除了then,其他的promise函数则可能不同。如果你需要一个你的库不包含的函数,你可以将一个基于你的库的promise包装到一个新的,基于含有你所需函数的库创建的promise里面。例如,JQuery的promise有时为人所诟病。那么你可以将其包装到Q,$q,mpromise,或者kew库的promise中进行操作。 |
郭振华oo
|
结语现在我写了这篇文章,而一年前我却是犹豫要不要拥抱promise的那个。我只是单纯地想完成一项工作。 我不想学习新的API,或是打破我原来的代码(因为误解了promise)。我曾经如此错误地认为!当我下了一点注时,就轻易就赢得了可喜的成果。 在这篇文章中,我已经简单给出了一个单一的promise,promise链,和一个并行的promise的promise的的例子。 Promises不难使用。如果我可以使用它们,任何人都可以。 要查看完整的概念,我支持你点击专家写的参考指南。从Promises/A 的参考开始,从事实上的标准JavaScript的Promise 开始。 如果你还没有直接使用的promise,试一下。下定决心:你会有一个不错的体验。我保证! – Lou Mauget, asktheteam@keyholesoftware.com 参考链接 |
相关推荐
To overcome these limitations, a concept called JavaScript promises is rising rapidly in popularity. Promises makes writing complex logics more manageable and easy. This book starts with an ...
Which parts of promises are synchronous and which are asynchronous How to effectively use promise chains to simplify your code The best way to catch errors in promises How to create your own promises ...
JavaScript. It has an evolving context that will lead you from a beginner's level to the master level of promises. Every chapter of this book will give you an outline to achieve a specific goal that ...
promise.js 是 Promises 的轻量级 JavaScript 实现。 Promises 提供了 callback-passing 的替代方案,异步函数返回一个 Promise 对象可附加到 callbacks 中。 示例代码: function asyncfoo() { var p = new ...
JavaScript中的Promise是异步编程的一种解决方案,它解决了回调地狱(Callback Hell)问题,使得复杂的异步操作更加清晰、可读性更强。Promise/A+规范是Promise实现的一个标准,旨在提供一致性和可移植性。该规范...
JavaScript Promises 是一种异步编程解决方案,用于处理可能需要时间完成的操作,如网络请求或文件读取。在JavaScript中,Promise对象代表一个异步操作的最终完成(或失败)及其结果值。Promises的设计思想是解决回...
Explore the latest tools and techniques at the forefront of concurrent programming, including JavaScript promises, web workers, and generators Learn how concurrent and parallel programming can help ...
总的来说,Promises 是现代 JavaScript 开发中处理异步操作的关键工具。它们提高了代码的可读性、可维护性和错误处理能力,使得编写优雅、安全的 JavaScript 代码变得更加容易。通过学习和熟练掌握 Promises,你可以...
pinkyPromise是一个超简单的 promises 库,旨在提供对 JavaScript promises 内部工作的洞察。 它不符合规范或用于生产用途。 原始博客文章: 。 用法 // take an async function function incrementAsync ( n , cb...
这涉及到回调函数、Promises、async/await等概念,这些是处理诸如网络请求、文件读写等耗时操作的关键。 6. ES6新增特性:ECMAScript是JavaScript的标准化规范。ECMAScript 6(ES6)引入了许多新特性,如箭头函数、...
《*** Ebook Part 1 The JavaScript language (2019)》是一本关于JavaScript语言的现代教程,其内容涵盖了JavaScript的基础和进阶知识,特别是DOM(文档对象模型)的相关知识。本书对于初学者和有经验的开发者都有很...
```javascript const { makePromisesSafe } = require('make-promises-safe'); // 启动全局的unhandled rejection处理器 makePromisesSafe(); ``` 3. 此后,所有未被捕获的Promise拒绝错误都会被记录,并在...
Next, you will move on to learn about DOM optimization, JavaScript promises, and web workers to better break up your large codebase. You will also learn about JavaScript performance on mobile ...
Next, you will move on to learn about DOM optimization, JavaScript promises, and web workers to better break up your large codebase. You will also learn about JavaScript performance on mobile ...
在这个特定的项目"HTTP-Library-using-Promises"中,开发人员选择利用JavaScript的Promise特性来构建一个HTTP库,同时使用了Fake API以模拟实际的网络服务。Promise是ES6引入的一种异步编程解决方案,它允许我们以一...
, AMD, Asynchronous Operations, Callbacks, Promises and Deferreds, Code Quality, Function Polymorphism, Function Scope, Hoisting and Closures, Functional Programming and Stateless Functions, ...