【发布时间】:2016-01-08 04:04:45
【问题描述】:
我开始使用 Promise 并尝试使用它们而不是回调来避免回调地狱。异步函数是来自 MongoDB、Redis、bcrypt 模块等的函数的混合。我能够做到这一点:
var insert = Q.denodify(db.collection(USERS).insert);
var createCollection = Q.denodify(db.createCollection);
var sadd = Q.denodify(redisClient.sadd);
var sismember = Q.denodify(redisClient.sismember);
var genSalt = Q.denodify(bcrypt.genSalt);
var hash = Q.denodify(bcrypt.hash);
// SANITY CHECK
// a "name" parameter is required
if(!req.body.name || !isValidName(req.body.name))
return next(get400InvalidNameError());
// SANITY CHECK
// a "key" is optional
// if one is supplied, it must be valid
// this key will be hashed later
if(req.body.key){
if(!isValidKey(req.body.key))
return next(get400InvalidKeyError());
}
// STEPS:
// 1.
// check Redis cache to see if the "name" is already taken
// if yes, return error. if no, continue
// 2.
// construct a "user" object with name = req.body.name
// 3.
// req.body.key provided?
// if yes, generate salt and hash the key. Set user.key = hash
// if not, continue
// 4.
// create a collection in MongoDB with the same name as req.body.name
// 5.
// add req.body.name to cache
// 6.
// send a response to user using res.json() / res.end()
sismember(USERS,req.body.name)
.then(createUserObj,errHandler)
.then(genSalt(10),errHandler)
.then(hash(req.body.key,salt))
.then(createCollection(req.body.name),errHandler)
.then(sadd(USERS,req.body.name),errHandler)
.then(insert(user),errHandler)
.then(get200UserCreated,errHandler)
让我感到困惑的是最后一部分,所有这些功能都是then()-ed 在一起的。我有几个问题:
1. 如何将一个异步函数的结果提供给另一个函数?
2. 如何有条件地决定执行哪些函数?例如,我只想在提供req.body.key 时生成盐和哈希。
3. 我的then() 序列是否正确?
【问题讨论】:
-
1.这就是一个承诺的工作方式,一个已解决的承诺的结果成为下一个然后的参数 -
如果您花点时间看一下,可以在 StackOverflow 上轻松找到问题 1 和 2 的答案。至于 3,不是,因为你在定义
then参数时是立即调用函数,而不是定义稍后会调用的函数。
标签: javascript node.js asynchronous promise q