关于护照序列化/反序列化用户中的回调函数的困惑
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 个参数,在该特定函数级别上的标签是 user
和 done
。
他们给你留了一些空间,你可以用你自己的代码来填充。你可以知道这将如何表现。他们让你有机会实现自己的逻辑。
简单示例:
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
的示例很好地说明了为什么它可能很强大。
太棒了!谢谢以上是关于关于护照序列化/反序列化用户中的回调函数的困惑的主要内容,如果未能解决你的问题,请参考以下文章
TypeError:User.findById 不是反序列化用户的函数