了解node.js中的promise

ajs*_*sie 146 javascript node.js promise

根据我的理解,有三种方法可以调用异步代码:

  1. 事件:例如. request.on("event", callback);
  2. 回调:例如. fs.open(path, flags, mode, callback);
  3. 承诺

我找到了一个承诺库https://github.com/kriszyp/node-promise,但我没有得到它.

有人可以解释一下什么是承诺,为什么我应该使用它?

另外,为什么它从Node.js中删除了?

eny*_*nyo 98

由于这个问题仍然有很多观点(像我的一样),我想指出:

  1. node-promise对我来说相当死(最后一次提交大约是1年前)并且几乎没有测试.
  2. 期货模块看起来很臃肿,我和被严重记录(我认为的命名约定是有害的)
  3. 最好的方法似乎是q框架,它既活跃又有充分的文档记录.

  • 2014年更新 - [tag:Bluebird]是迄今为止最快的,也是目前调试能力最强的. (23认同)
  • 检查这个https://github.com/medikoo/deferred,Q是第一个,它肯定是后来出现的许多实现的灵感,但遗憾的是它在某些部分非常缓慢且太"理论化",它没有适应一些真实场景 (9认同)

Pau*_*son 90

node.js中的promise承诺做一些工作,然后有单独的回调,可以执行成功和失败以及处理超时.在node.js中考虑promises的另一种方法是它们是只能发出两个事件的发射器:成功和错误.

关于promises的很酷的事情是你可以将它们组合成依赖链(只有当Promise A Promise B完成时才做Promise C ).

通过从核心node.js中删除它们,它创建了构建模块的可能性,这些模块具有可以位于核心之上的不同promises实现.其中一些是节点承诺期货.

  • @weng不,不是. (10认同)

Hri*_*shi 19

承诺是一个"事物",它代表了操作的"最终"结果.这里需要注意的是,它抽象出事情发生的细节,并让你专注于事情发生应该发生的事情.这将产生干净,可维护的代码,而不是在回调内部的回调内部进行回调,您的代码看起来有点像:

 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
 });
Run Code Online (Sandbox Code Playgroud)

承诺的规范说明了承诺

then
Run Code Online (Sandbox Code Playgroud)

方法应返回在给定的successHandler或failureHandler回调完成时满足的新promise.这意味着当您有一组需要执行的异步任务时,您可以将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
Run Code Online (Sandbox Code Playgroud)

要了解更多关于承诺及其超酷的原因,请查看Domenic的博客:http://domenic.me/2012/10/14/youre-missing-the-point-of-promises/


Ton*_*gan 12

这个来自PouchDB作者的Promises 新教程可能是我见过的最好的.它明智地涵盖了经典的菜鸟错误,显示了正确的使用模式,甚至还有一些仍然常用的反模式 - 即使在其他教程中也是如此!

请享用!

PS我没有回答这个问题的其他部分,因为他们已经被其他人很好地覆盖了.


Noe*_*ams 7

Mike Taulty 有一系列视频,每个视频不到十分钟,描述了WinJS Promise库的工作原理.

这些视频非常有用,Mike通过一些精心挑选的代码示例设法展示了Promise API的强大功能.

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
     });
Run Code Online (Sandbox Code Playgroud)

如何处理例外的处理特别好.

尽管有WinJs参考,但这是一个普遍感兴趣的视频系列,因为Promise API在其众多实现中大致相似.

RSVP是一个轻量级的Promise实现,它通过了Promise/A +测试套件.我非常喜欢API,因为它的风格类似于WinJS界面.

2014年4月更新

顺便说一句,WinJS库现在是开源的.


lla*_*bda 5

Promise的另一个优点是,错误处理以及引发和捕获异常的方法比尝试使用回调处理要好得多。

蓝鸟库实现承诺,并为您提供一流长的堆栈跟踪,速度非常快,并警告有关未被捕获的错误。根据http://bluebirdjs.com/docs/benchmarks.html的介绍,与其他promise库相比,它还更快,使用的内存更少。