关于护照序列化/反序列化用户中的回调函数的困惑

Posted

技术标签:

【中文标题】关于护照序列化/反序列化用户中的回调函数的困惑【英文标题】:Confusion about callback function in passport serialize/deserialize user 【发布时间】:2020-09-08 12:17:45 【问题描述】:

当我们在 JS 中编写代码时,我有一个关于异步/同步的问题,我已经进行了谷歌搜索,但我仍然有点困惑。

我知道当我们想确保回调函数只有在外部函数中的异步任务(例如访问数据库)完成后才执行时,我们使用回调函数。我了解反序列化和序列化用户的工作原理。

我很困惑,为什么当我们使用passport.js 序列化用户或反序列化用户时,我们需要这样的回调函数?

passport.serializeUser((user, done) => 

done(null, user.id);

);

如果我们想要的只是作为参数传递给serializeUser() 的内部箭头函数仅在serializeUser() 完成后执行。或者为什么我们需要将它作为回调函数传递,而不是在 serializeUser() 下方调用箭头函数?我以为 JS 是同步的,所以它会在 serializeUser() 完成后执行箭头函数?

我只在护照文档中找到了关于如何使用它的 serializeUser() 文档,但没有找到它的实现,所以我也很困惑 serializeUser()deserializeUser()(或任何其他护照函数)是否是异步函数?

谢谢!

【问题讨论】:

serializeUser 将随时运行回调函数。您需要将其作为函数传递,因为这就是 serializeUser 的实现方式。您不能简单地运行“下面”serializeUser 的函数,因为您需要回调函数接收的参数(例如,用户)。见***.com/q/27637609/438992。 可以在你承诺的下面编码它并使用 async/await @DaveNewton:谢谢。我想知道这是否仍然意味着只有在 serializeUser() 完成后才调用回调函数? @dandavis:谢谢。我想知道你能详细说明如何在这里使用 promise 吗?我也是关于 async/await 的使用。我想知道serializeUser() 不是异步的吗?因为我们需要使用 async/await。 @bubblerain 只要serializeUser 调用它,就会调用回调。它可能在其正常流程的末尾,也可能不是——您所能做的就是查看源代码以了解如何/何时使用回调。 【参考方案1】:

这是github上这个函数的一个片段(https://github.com/jaredhanson/passport/blob/08f57c2e3086955f06f42d9ac7ad466d1f10019c/lib/authenticator.js)。

如您所见,此函数采用fn 参数。然后它检查它是否是一个函数。如果是,它会将其推送到this._serializers。后来它对它做了“一些魔法”,我认为现在不重要了。

正如您在 jsdoc 中看到的,serializeUser 的目的是注册一个用于序列化用户对象的函数。因此,您传递了一些稍后在代码中调用的函数,该代码带有 2 个参数,在该特定函数级别上的标签是 userdone

他们给你留了一些空间,你可以用你自己的代码来填充。你可以知道这将如何表现。他们让你有机会实现自己的逻辑。

简单示例:

function doSomeMagic(fn) 
  // I do some my staff
  const a = 5;
  const b = 10;

  // and now I let you decide what to do
  // you can implement your own logic in my function
  const result = fn(a, b);

  console.log(result);


doSomeMagic((a, b) => 
  return a * b;
);

doSomeMagic((a, b) => 
  return a + b;
);

//output:
// 50
// 15

这正是他们所做的。你可以接受我的功能,我给你两个参数做任何你想做的事。你可以乘,加,减,任何你想要的。我不必编写单独的函数来进行数学运算,我可以编写一个,将值作为参数传递,然后让您决定要执行的操作。这并不意味着我的代码将以异步方式运行。

【讨论】:

嗨雅库布!谢谢你。我想我现在意识到回调可以是异步和同步的。所以我认为在这种情况下将函数传递给serializeUser() 的目的是让我们可以自己实现该函数,而不是异步回调的正常目的? 是的。留下空白让其他人用他自己的代码填充它只是一个“功能”。例如。你可以在那里添加console.log('hello');,它会在每次执行时打印出来。我认为doSomeMagic 的示例很好地说明了为什么它可能很强大。 太棒了!谢谢

以上是关于关于护照序列化/反序列化用户中的回调函数的困惑的主要内容,如果未能解决你的问题,请参考以下文章

护照反序列化用户未在帆中调用

当护照js中的序列化和反序列化调用时

TypeError:User.findById 不是反序列化用户的函数

2:如何反序迭代一个序列(字符串,列表,元组)

测试Hessian反序反序列化 客户端少字段和多字段时能否成功

nodejs护照身份验证令牌