Node.js承诺、异步或仅回调

Node.js承诺、异步或仅回调,node.js,asynchronous,callback,promise,Node.js,Asynchronous,Callback,Promise,你能向初学者解释一下“承诺”、“异步”和“回调”之间的区别吗。这些术语如何相互关联?这些是同一件事吗?不同的东西?什么时候使用哪个?异步是启动计算并提供函数或注册处理程序的一般设计模式,当计算完成时,该处理程序最终将被调用,并带有计算结果(而不是在开始额外工作之前阻塞并等待计算完成)。如果没有异步,同时启动多个计算需要使用线程 “回调”是指为异步计算提供的函数,该计算完成后将调用该函数。它被称为“回调”,因为它被异步函数调用,在被调用时,它将控制流返回到您可以控制的代码中 “Promise”是一

你能向初学者解释一下“承诺”、“异步”和“回调”之间的区别吗。这些术语如何相互关联?这些是同一件事吗?不同的东西?什么时候使用哪个?

异步是启动计算并提供函数或注册处理程序的一般设计模式,当计算完成时,该处理程序最终将被调用,并带有计算结果(而不是在开始额外工作之前阻塞并等待计算完成)。如果没有异步,同时启动多个计算需要使用线程

“回调”是指为异步计算提供的函数,该计算完成后将调用该函数。它被称为“回调”,因为它被异步函数调用,在被调用时,它将控制流返回到您可以控制的代码中

“Promise”是一个特定的JavaScript原型和相关框架,它为以异步方式编写的代码带来一致性。Promise表示异步计算,该计算可能已完成,也可能尚未完成(成功或失败),它提供了一种对结果进行操作或处理错误的方法,而不管异步计算的完成状态如何。Promise API还提供用于组合多个异步计算的输出的实用程序(例如,在下一次计算之前等待一个或所有异步计算完成)

举一个没有承诺的简单例子:

var addThen = function(a, b, handler) {
  var result = a + b;
  handler(result);
};

// ...
addThen(2, 3, console.log);  // prints 5
// ...
以及具有承诺的等价物:

var add = function(a, b) {
  return Promise.resolve(a + b);
};

// ...
add(2, 3).then(console.log); // prints 5
// ...

异步代码可以编写有承诺和无承诺,但使用承诺的主要优点是一致性(例如,成功回调和失败回调在参数列表中的位置,是否支持失败回调,等等)并支持可以将它们组合在一起的库。

您应该使用哪一个库是基于意见的。其他问题已经单独提出了:-。至于async library vs Promissions,Promissions更强大、更可组合,但这也是我的观点。在我看来,在学习的过程中,您应该首先学习JavaScript并发模型(也就是说,除了API提供给您的“主机函数”,所有东西都是同步的)。函数是如何接受函数参数的,更一般地说,是如何接受函数参数的,最后才接受——承诺是如何工作的(它们不是神奇的:)。只有当你学会了这些东西,我才会使用承诺,在我看来,承诺是回调的更好的选择,因为它们能更好地处理错误,更好地组合。这是一个有效的问题,而不是基于观点。这些术语高度相关,对不同术语进行澄清是适当的。请重新打开。@MichaelAaronSafyan在编辑之前它是基于意见的,编辑之后它是一个非常接近的副本。根据我的经验,大多数事情都可以通过使用承诺来实现,而且它可以清楚地理解流程。使用承诺的缺点是,使用承诺的项目往往在任何地方都使用承诺,这有时会导致需要包装不使用承诺的模块。异步可以很容易地与大量使用CBs相结合,因此在长流的情况下,它可以提供更好的结构。但正如@Benjamin Gruenbaum所提到的,在进一步讨论之前,您应该首先了解JS并发模型。这是一个值得一读的承诺:回调不一定是异步的,它是关于控制反转的——它可以作为命令或计算策略。例如,在
[1,2,3,4,5,0,4].map(Boolean)
中,没有异步发生,但函数
Boolean
函数作为回调传递。这实际上是关于控制反转。承诺不是一个JavaScript原型,也不是一个框架,它们是像Mark Miller和Barbara Liskov这样的人在JavaScript成为一种东西之前提出的一个概念。此外,我不会将“异步”称为设计模式——这种模式是。此外,在没有线程的情况下,不需要线程来执行并发(一个很好的反例是协同路由)。通过回调实现的JavaScript并发本身就是并发,而多个计算同时发生的事实是由于主机对象而不是JavaScript(在ES6之前JavaScript根本没有并发的概念)。所有这些都是非常好的注释。就像“并行”与“并发”一样,这实际上取决于我们对语言的精确程度,以及关注的焦点是代码的结构还是执行顺序。不过,您是对的,async实际上假设存在一些延迟(例如,由于网络),而我提供的虚拟示例立即提供了结果。CPS可以用于即时结果,但它在异步环境中更有用、更受欢迎。现在浏览器中有一个Promise的具体实现,尽管在此之前有各种不同的版本。考虑到标签“JavaScript”和“Node.js”,我认为有理由假设这是OP的想法,而不是一般的Promise/Future/whatever模式。我还应该指出,协同路由基本上是轻量级的用户空间线程,但它们基本上是一样的。对于OP的知识水平,我认为这种区别是没有帮助的。