了解回调和承诺。它是不是正确?

Posted

技术标签:

【中文标题】了解回调和承诺。它是不是正确?【英文标题】:Understanding callbacks and promises. Is this correct?了解回调和承诺。它是否正确? 【发布时间】:2020-11-29 12:07:06 【问题描述】:

所以,我目前正在学习回调和承诺,但在观看教程时我总是被绊倒。所以我想我会把它放在一个例子中,看看是否有人能告诉我我的想法是否正确。我目前正在使用 MongoDB 和 Mongoose。

这是一段取自教程的示例代码。我相信这被认为是回调?


  user.save((err) => 
    if (err) 
      return res.status(400).json(
        error: "You are not authorized to perform this action.",
      )
    );

然后这会被认为是一个承诺?


user.save().catch(err => 
   return res.status(400).json(
      error: "You are not authorized."
   )
)

与回调相比,使用 Promise 是否有任何性能优势,反之亦然?

谢谢!

【问题讨论】:

阅读“回调地狱”的概念,您将开始了解 Promise 是如何更容易使用,更重要的是更容易用捕获错误 【参考方案1】:

回调和承诺是不同的,但共享一些概念。 回调只是一个作为参数传递给另一个函数的函数,该函数可以随时执行。 例如:

function iNeedACallback(callback)

  // execute a bunch of code...
  
  // use the callback function provided 
  callBack("a function called 'iNeedACallback'")

const callback = (fromFunction) => console.log("I am a callback function called from: " + fromFunction);

// Execute iNeedACallback by passing in the callback
iNeedACallback(callback);

上面的代码是一个非常简单的回调函数实例 - 现在它可以按顺序执行(如上面的示例),也可以是事件循环上的异步操作。 (有关事件循环的更多信息:Why do you need to await AJAX calls in JS but not in C#?)

Promise 使用回调函数以传统方式处理异步代码。 Promise 的性质推断它的一些代码将在异步执行时放置在事件循环中,并且在等待网络调用等操作时不会阻塞任何其他代码。 例如:

const promise = new Promise((resolve, reject) => 
 setTimeout(() => 
    const text = "i was only called after 2 seconds :(";
    resolve(text);
    , 2000)
)

promise.then((text) => console.log(text))
console.log("i got called immediately :)")

//Output:
//i got called immediately :)
//i was only called after 2 seconds :(

在上面的示例中,我们提供了一个回调函数,当异步操作完成时执行(例如 setTimeout),其中最常见的用例是网络调用(例如 HTTP 请求)或 TCP 连接到数据库(例如 mongodb)。

回到你原来的问题——你的假设是正确的,因为你对回调和承诺的演示是正确的,而你关于性能的问题是正确的。 javascript 是单线程的,所以如果你的回调函数被放置在事件循环中(它可能是也可能不是),那么它不会阻塞主执行调用堆栈。 Promise 本质上是异步操作,因此它们将始终放置在事件循环中,因此性能因素取决于回调函数的底层实现 - Promise 将是异步的,因为一些常规回调可能是顺序的和同步的。

【讨论】:

以上是关于了解回调和承诺。它是不是正确?的主要内容,如果未能解决你的问题,请参考以下文章

你如何正确地承诺请求?

如何使用 Promise 和 node.js 正确检查和记录 http 状态代码?

在承诺回调中发送数组响应,但响应为空白

干净的代码和嵌套的承诺 [重复]

Jquery Promise & When without Ajax

如何正确地打破承诺链?