148

据我了解,调用异步代码的方式有以下三种:

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

我找到了node-promise 库,但我不明白。

有人可以解释一下承诺的全部内容以及我为什么要使用它吗?

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

4

9 回答 9

98

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

  1. node-promise对我来说看起来很死(最后一次提交是大约 1 年前)并且几乎不包含任何测试。
  2. futures模块对我来说看起来很臃肿,而且文档很糟糕(我认为命名约定很糟糕)
  3. 最好的方法似乎是q 框架,它既活跃又有据可查。
于 2012-05-16T20:41:46.490 回答
91

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

Promise 很酷的一点是你可以将它们组合成依赖链(只有在 Promise APromise B 完成时才执行 Promise C)。

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

于 2010-11-28T14:05:45.660 回答
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
 });

承诺的规范指出承诺的

then

当给定的 successHandler 或 failureHandler 回调完成时,方法应该返回一个新的 Promise。这意味着当您有一组需要执行的异步任务时,您可以将 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

要了解更多关于 Promise 以及为什么它们超级酷的信息,请查看 Domenic 的博客:http ://domenic.me/2012/10/14/youre-missing-the-point-of-promises/

于 2014-05-23T16:11:15.220 回答
12

这个来自PouchDB作者的关于 Promises 的新教程可能是我见过的最好的教程。它明智地涵盖了经典的菜鸟错误,向您展示了正确的使用模式,甚至一些仍然常用的反模式——即使在其他教程中!

享受!

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

于 2015-05-25T01:39:00.093 回答
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
     });

如何处理异常的处理特别好。

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

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

2014 年 4 月更新

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

于 2012-12-13T15:00:11.850 回答
5

Promise 的另一个优点是错误处理和异常抛出和捕获比尝试使用回调处理要好得多。

bluebird库实现了Promise 并为您提供了很长的堆栈跟踪,速度非常快,并警告未捕获的错误。根据http://bluebirdjs.com/docs/benchmarks.html,它也比其他 Promise 库更快并且使用更少的内存

于 2014-03-14T15:30:22.283 回答
4

Promise 到底是什么?

Promise 只是一个表示异步操作结果的对象。承诺可以处于以下 3 种状态中的任何一种:

pending :: 这是初始状态,表示 promise 既没有被履行也没有被拒绝。

已履行:这意味着承诺已经履行,意味着承诺所代表的价值可以使用。

拒绝:: 这意味着操作失败,因此无法履行承诺。除了状态之外,还有三个与我们真正需要了解的承诺相关的重要实体

  1. executor function :: executor function 定义了需要执行的异步操作,其结果由 promise 表示。一旦 Promise 对象被初始化,它就开始执行。

  2. resolve::resolve 是传递给执行器函数的参数,如果执行器运行成功,则此解析称为传递结果。

  3. reject::reject 是传递给执行器函数的另一个参数,在执行器函数失败时使用。失败原因可以传递给reject。

所以每当我们创建一个 promise 对象时,我们必须提供 Executor、Resolve 和 Reject。

参考 :: Promise

于 2017-05-18T20:18:45.560 回答
0

我最近也在研究 node.js 中的 Promise。迄今为止,由于其速度和资源使用, when.js似乎是要走的路,但是q.js上的文档让我有了更好的理解。所以使用 when.js 但使用 q.js 文档来理解这个主题。

来自github 上的q.js自述文件:

如果一个函数不能在没有阻塞的情况下返回值或抛出异常,它可以返回一个 Promise。Promise 是一个对象,它表示函数最终可能提供的返回值或抛出的异常。Promise 也可以用作远程对象的代理来克服延迟。

于 2014-06-13T10:09:33.780 回答
0

Promise 对象表示异步操作的完成或失败。

所以为了实现一个承诺,你需要两个部分:-

1.创造承诺:

Promise 构造函数接受一个称为 executor 的函数,该函数有 2 个参数 resolve 和 reject。

function example(){
   return new Promise (function(resolve , reject){   //return promise object
      if(success){
         resolve('success');  //onFullfiled
      }else{
         reject('error');     //onRejected
      }
   })
}

2.处理承诺:

Promise 对象有 3 种方法来处理 Promise 对象:-

1.Promise.prototype.catch(onRejected)

2.Promise.prototype.then(onFullfiled)

3.Promise.prototype.finally(onFullfiled,onRejected)

example.then((data) =>{
  //handles resolved data
  console.log(data); //prints success     
}).catch((err) => {
  //handles rejected error 
  console.log(err);  //prints error
})
于 2020-05-24T17:07:40.537 回答