了解node.js中的承诺
从我所了解的有三种方法调用asynchronous代码:
- 事件:例如。
request.on("event", callback);
- callback:例如。
fs.open(path, flags, mode, callback);
- 承诺
我发现一个承诺库https://github.com/kriszyp/node-promise,但我不明白。
有人可以解释什么是承诺,为什么我应该使用它?
另外,为什么从Node.js中删除?
node.js中的承诺承诺做一些工作,然后有单独的callback,将执行成功和失败,以及处理超时。 另一种思考node.js中的promise的方法是,它们是可以只发出两个事件的发射器:成功和错误。
关于promise的很酷的事情是你可以把它们组合成依赖链(只有当Promise A 和 Promise B完成时才做Promise C)。
通过从核心node.js中删除它们,创build了可以在不同核心之上实现承诺的模块。 其中一些是节点承诺和期货 。
既然这个问题还有很多意见(比如我的),我想指出的是:
- node-promise对我来说看起来相当死(最后一次提交大约在1年前)并且几乎不包含任何testing。
- 期货模块对我来说看起来很臃肿,而且logging不准确(我认为命名约定是不好的)
- 最好的方式似乎是q框架 ,这是积极的,有据可查的。
承诺是一个“事物”,可以说是一个操作的“最终”结果。 这里需要注意的一点是,它会抽象出发生什么事情的细节,并允许您将注意力集中在事件发生后应该发生的事情上。 这将导致干净的,可维护的代码,而不是在callback中的callback里面有一个callback,你的代码看起来有点像:
var request = new Promise(function(resolve, reject) { //do an ajax call here. or a database request or whatever. //depending on its results, either call resolve(value) or reject(error) //where value is the thing which the operation's successful execution returns and //error is the thing which the operation's failure returns. }); request.then(function successHandler(result) { //do something with the result }, function failureHandler(error) { //handle });
承诺的规范说明了一个承诺
then
方法应该返回一个新的promise,当给定的successHandler或者failureHandlercallback完成时,这个promise就会被执行。 这意味着当你有一组需要执行的asynchronous任务时,你可以链接在一起,并确保操作的顺序得到保证,就像你使用callback一样。 所以不是在callback里面的callback中传递callback,而是带有链接的promise的代码如下所示:
var doStuff = firstAsyncFunction(url) { return new Promise(function(resolve, reject) { $.ajax({ url: url, success: function(data) { resolve(data); }, error: function(err) { reject(err); } }); }; doStuff .then(secondAsyncFunction) //returns a promise .then(thirdAsyncFunction); //returns a promise
要了解更多关于承诺和为什么他们是超级酷,结帐Domenic的博客: http : //domenic.me/2012/10/14/youre-missing-the-point-of-promises/
这个PouchDB作者的Promise 新教程可能是我见过的最好的。 它明智地涵盖了经典的菜鸟错误,向您展示正确的使用模式,甚至还有一些仍然常用的反模式 – 即使在其他教程!
请享用!
PS我没有回答这个问题的其他部分,因为他们已经很好地覆盖了他们。
Mike Taulty 有一系列video ,每个video都不到十分钟,描述了WinJS Promise库的工作原理。
这些video非常丰富,Mike通过一些精心挑选的代码示例,展示了Promise API的强大function。
var twitterUrl = "http://search.twitter.com/search.json?q=windows"; var promise = WinJS.xhr({ url: twitterUrl }); promise = promise.then( function (xhr) { }, function (xhr) { // handle error });
如何处理例外情况特别好。
尽pipe有WinJs引用,但这是一个普遍感兴趣的video系列,因为Promise API在其许多实现方面大致相似。
RSVP是一个轻量级的Promise实现,通过了Promise / A +testing套件。 我非常喜欢这个API,因为它的风格与WinJS界面相似。
2014年4月更新
顺便说一下,WinJS库现在是开源的 。
承诺的另一个优点是error handling和exception抛出和捕获比用callback处理更好。
蓝鸟库实现承诺,并给你很长的堆栈跟踪,速度非常快,并警告未被捕获的错误。 根据http://bluebirdjs.com/docs/benchmarks.html ,它也比其他承诺库更快并且使用更less的内存。
什么是一个承诺?
承诺仅仅是表示asynchronous操作结果的对象。 承诺可以在以下三种状态中的任何一种:
挂起 ::这是最初的状态,意味着承诺既没有履行也没有被拒绝。
履行 ::这意味着承诺已经实现,意味着承诺代表的价值已经准备好被使用。
被拒绝 ::这意味着操作失败,因此不能履行承诺。 除了国家之外,还有三个与我们真正需要了解的承诺相关的重要实体
-
executor function :: executor函数定义需要执行的asynchronous操作,其结果由promise来表示。 只要promise对象被初始化就开始执行。
-
resolve :: resolve是一个传递给executor函数的参数,如果executor运行成功,那么这个parsing就是传递结果。
-
reject :: reject是传递给执行程序函数的另一个参数,在执行程序函数失败时使用。 失败的原因可以传递给拒绝。
所以无论何时我们创build一个promise对象,我们都要提供Executor,Resolve和Reject。
参考:: 承诺
我最近也在研究node.js中的promise。 迄今为止,由于其速度和资源的使用, when.js似乎是一条路,但q.js上的文档给了我更多的理解。 所以使用when.js但是q.js文件来理解这个主题。
从github上的q.js自述文件:
如果一个函数不能返回一个值,或者在没有阻塞的情况下抛出一个exception,它可以返回一个promise。 promise是一个表示函数可能最终提供的返回值或抛出的exception的对象。 承诺还可以用作远程对象的代理来克服延迟。