理解 Node.js 中的 promise

IT技术 javascript node.js promise
2021-01-31 08:19:49

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

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

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

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

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

6个回答

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

  1. node-promise对我来说看起来很死(最后一次提交是大约 1 年前)并且几乎不包含任何测试。
  2. 期货module看起来很臃肿的我,被严重记录(我认为的命名约定是有害的)
  3. 最好的方法似乎是q framework,它既活跃又记录良好。
2014 年更新 - bluebird是迄今为止速度最快、调试能力最强的版本。
2021-03-29 08:19:49
我会查看 RSVP.js youtube.com/ 的一位创建者关于Promise的视频...
2021-03-31 08:19:49
也检查这个github.com/medikoo/deferred,Q 是第一个,它绝对是后来出现的许多实现的灵感,但不幸的是它在某些部分非常缓慢且过于“理论化”,它不能很好地与某些真实世界场景
2021-04-06 08:19:49

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

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

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

一个promise是一个“事物”,可以说是代表一个操作的“最终”结果。这里要注意的一点是,它抽象了某事发生的细节,并让您专注于某事发生应该发生的事情。这将产生干净、可维护的代码,而不是在回调内部的回调中包含回调,您的代码看起来有点像:

 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
 });

Promise的规范指出Promise的

then

方法应该返回一个新的promise,当给定的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/

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

享受!

PS 我没有回答这个问题的其他一些部分,因为其他人已经很好地涵盖了这些部分。

事实上,教程中他们声称是反模式的代码需要循环和条件的嵌套,并且不能像他们建议的那样容易扁平化。
2021-03-13 08:19:49
我认为这个仅链接的答案最好是评论。请至少将这篇文章的要点放在您的答案中。
2021-03-18 08:19:49
高级错误 #4也可以使用更多不同的方法来解决,请参阅如何在 .then() 链中访问先前的Promise结果?他们建议关闭模式似乎不是很受欢迎)。
2021-03-31 08:19:49
我唯一的歉意是强迫你在高级错误 #4 的结尾阅读幽默。
2021-04-08 08:19:49

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/A+ 测试套件的轻量级 Promise 实现。我非常喜欢 API,因为它在风格上与 WinJS 界面相似。

2014 年 4 月更新

顺便提一下,WinJS 库现在是开源的

@noel 感谢您分享上述链接,这是一个很好的 Promise 介绍系列,我同意 WinJS 的细节无关紧要,因为整体方法/主题是通用的。
2021-03-22 08:19:49
很好的例子。我也修复了你的第一个链接,它已经死了
2021-04-04 08:19:49
+1。这是我见过的第一个对我来说有意义并且使用起来很直观的例子不知何故,我的大脑无法解析流行的 Q 库文档中的所有deferredsresolvedeferred.promise.then和预定义promiseActions你有没有机会知道Node.js这么简单的东西
2021-04-10 08:19:49