理解 Node.js 中的承诺

据我所知,调用异步代码有三种方法:

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

我找到了 节点承诺库节点承诺库但我不明白。

谁能解释一下什么是承诺,以及我为什么要使用它?

还有,为什么从 Node.js 中删除它?

99815 次浏览

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

关于承诺最酷的事情是你可以将它们组合成依赖链(只有当承诺 A 还有承诺 B 完成时才做承诺 C)。

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

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

  1. Node- 承诺 在我看来相当死气沉沉(上一次提交是在大约1年前) ,而且几乎不包含任何测试。
  2. 在我看来,未来模块非常臃肿,文档记录也很糟糕(我认为命名约定很糟糕)
  3. 最好的方法似乎是 Q 框架,它既活跃又有充分的文档记录。

Mike Taulty 有一系列的视频,它们每个都不到10分钟长,描述了 WinJS 承诺库是如何工作的。

这些视频信息量很大,Mike 通过一些精心选择的代码示例展示了 PromisAPI 的强大功能。

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 的参考资料,但这是一个普遍感兴趣的视频系列,因为在它的许多实现中,ProjectAPI 大致相似。

RSVP 是一个轻量级的极限实现,它通过了极限/A + 测试套件。我非常喜欢这个 API,因为它在风格上类似于 WinJS 接口。

2014年4月更新

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

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

青鸟库实现了承诺,提供了很长的堆栈跟踪,速度非常快,并对未捕获的错误发出警告。根据 http://bluebirdjs.com/docs/benchmarks.html的说法,它也比其他承诺库更快,使用的内存更少

承诺是一件“事情”,可以说是代表了一次行动的“最终”结果。这里需要注意的是,它抽象出了 什么时候发生的事情的细节,并允许您关注应该发生的事情。这将产生干净的、可维护的代码,在这些代码中,您的代码将不会在回调内部的回调中包含回调,而是看起来有点像:

 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

方法应该返回一个新的承诺,这个承诺在给定的 Success Handler 或 failureHandler 回调结束时实现。这意味着,当您有一组需要执行的异步任务时,您可以将承诺链接在一起,并确保操作的顺序得到保证,就像您使用了回调一样。因此,与其在回调内部的回调内部传递回调,不如将带有链式承诺的代码看作:

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/

我最近也在研究 node.js 中的承诺。到目前为止,由于其速度和资源的使用,什么时候 JS似乎是一种可行的方法,但是关于 Q.js的文档给了我更好的理解。所以使用 when. js 但是 q.js 文档来理解主题。

来自 github 上的 Q.js自述:

如果函数不能返回值或引发异常 它可以返回一个承诺。承诺是一个对象 表示函数的返回值或引发的异常 一个承诺也可以作为一个代理 克服延迟的远程对象。

这个 新教程的承诺从作者的 PouchDB可能是最好的,我见过的任何地方。它明智地涵盖了经典的新手错误显示您正确的使用模式,甚至一些反模式,仍然常用-即使在其他教程!

好好享受吧!

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

承诺到底是什么?

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

挂起 : : 这是初始状态,表示承诺既没有实现也没有被拒绝。

履行 : : 这意味着承诺已经履行,意味着承诺所代表的价值已经准备好被使用。

拒绝 : : 这意味着操作失败,因此无法实现承诺。 除了国家,还有三个重要的实体与我们真正需要理解的承诺有关

  1. 函数定义需要执行的异步操作,其结果由承诺表示。它在承诺对象初始化后立即开始执行。

  2. 是一个传递给执行器函数的参数,如果执行器成功运行,那么这个解析就被称为传递结果。

  3. 是传递给执行器函数的另一个参数,当执行器函数失败时使用它。失败原因可以传递给拒绝。

因此,每当我们创建一个承诺对象,我们必须提供执行器,解决和拒绝。

参考文献: : 我保证

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

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

1. 创造承诺:

允诺构造函数接受一个称为执行器的函数,该函数具有 2参数解析和拒绝。

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

2. 处理承诺:

承诺对象有三种处理承诺对象的方法:-

1、承诺、原型、捕捉(被拒绝)

2、承诺。原型。然后(onFullfile)

3. 誓言、原型、最终(onFullfile、 onRejected)

example.then((data) =>{
//handles resolved data
console.log(data); //prints success
}).catch((err) => {
//handles rejected error
console.log(err);  //prints error
})