节点.js链接多个承诺(与猫鼬)
node.js chain multiple promises (with mongoose)
以下是我正在处理的典型 promise 函数。
var _delete = function(t, id) {
return Promise.cast(Event.find({where: {id: id}}, {transaction: t}))
.then(function(d){
if (d) {
// ------- (*)
return Promise.cast(d.updateAttributes({status: -1}, {transaction: t}))
.then(function(){
// do inventory stuff
return Promise.cast(Inventory.update({}).exec())
.then(function(d){
// do something
})
}).then(function(){
// do product stuff
return Promise.cast(Product.update({}).exec())
.then(function(d){
// do something
})
})
} else {
return Promise.reject('this transaction list does not exist');
}
});
};
这看起来不错,直到我处理更复杂的更新/创建代码会变得非常混乱。
目前我正在做的是承诺是1.我有很多无用的返回true语句,唯一的目的是转到下一个.then语句2. 承诺以嵌套样式编程。此外,输入参数通常很复杂,并且有超过 1 个参数,所以我无法做这样的事情
.then(fun1).then(fun2)
。等
这使我无法'tap'
.then
语句来启用/禁用功能。
所以我的问题是我如何正确做到这一点? 谢谢。。
以下是我所说的真正丑陋的事情......
var _process = function(t, tid) {
var that = this;
return Promise.cast(Usermain.find({where: {transaction_id: tid}}))
.bind({}) // --- (*)
.then(function(d){
this.tmain = d;
return true; // ---- do nothing, just go to next thennable (is this correct)
}).then(function(){
return Promise.cast(Userlist.findAndCountAll({where: {transaction_id: tid}}))
}).then(function(d){
this.tlist = d;
return true; // ---- do nothing, just go to next thennable (is this correct)
}).then(function(){
if (this.tmain.is_processed) {
return Promise.reject('something is wrong');
}
if (this.tlist.count !== this.tmain.num_of_tran) {
return Promise.reject('wrong');
}
return Promise.resolve(JSON.parse(JSON.stringify(this.tlist.rows)))
.map(function(d){
if (d.is_processed) return Promise.reject('something is wrong with tran list');
return true; // goto next then
});
}).then(function(){
return Promise.cast(this.tmain.updateAttributes({is_processed: 1}, {transaction: t}));
}).then(function(){
return Promise.resolve(this.tlist.rows)
.map(function(d){
var tranlist = JSON.parse(JSON.stringify(d));
return Promise.cast(d.updateAttributes({is_processed: 1, date_processed: Date.now()}, {transaction: t}))
.then(function(d){
if (!d) {
return Promise.reject('cannot update tran main somehow');
} else {
if (tranlist.amount < 0) {
return Usermoney._payBalance(t, tranlist.user_id, -tranlist.amount);
} else {
return Usermoney._receiveBalance(t, tranlist.user_id, tranlist.amount);
}
}
});
});
});
}
你可以做两件事:
- 取消嵌套
then
回调 - 模块 化。这些"做产品的东西"和"做库存的东西"可能会成为它们自己的功能(甚至相同?
在这种情况下,取消嵌套可以执行以下操作(假设您不需要在注释部分中关闭):
function _delete(t, id) {
return Promise.cast(Event.find({where: {id: id}}, {transaction: t}))
.then(function(d){
if (d) {
return Promise.cast(d.updateAttributes({status: -1}, {transaction: t}));
else
throw new Error('this transaction list does not exist');
})
.then(function(){
// do inventory stuff
return Promise.cast(Inventory.update({}).exec())
})
.then(function(d){
// do something
})
.then(function(){
// do product stuff
return Promise.cast(Product.update({}).exec())
})
.then(function(d){
// do something
});
}
在我的项目中,我使用异步.js
我认为您需要将_process
方法分解为小动作
- 依赖于先前操作结果的操作 - 此处可能使用异步
waterfall
模式 - 不依赖于先前操作结果的操作,它们可以并行执行
- 使用一些自定义过程
这是我的应用程序中的一个示例:
async.waterfall([
function findUser(next) {
Users.findById(userId, function (err, user){
if(err) {
next(new Error(util.format('User [%s] was not found.', userId)));
return;
}
next(null, user);
});
},
function findUserStoriesAndSurveys(user, next) {
async.parallel([
function findStories(callback) {
// find all user stories
Stories.find({ UserGroups: { $in : user.Groups } })
.populate('Topic')
.populate('Episodes')
.exec(function(err, stories) {
if(err) {
callback(err);
return;
}
callback(null, stories);
});
},
function findSurveys(callback) {
// find all completed surveys
Surveys.find({
User: user
}).exec(function(err, surveys) {
if(err) {
callback(err);
return;
}
callback(null, surveys);
});
}
],
function(err, results) {
if(err) {
next(err);
return;
}
next(null, results[0], results[1]);
});
},
function calculateResult(stories, surveys, next) {
// do sth with stories and surveys
next(null, { /* result object */ });
}
], function (err, resultObject) {
if (err) {
res.render('error_template', {
status: 500,
message: 'Oops! Server error! Please reload the page.'
});
}
res.send(/* .... */);
});
请参考 异步文档 对于自定义过程,它确实包含很多常见模式,我也在我的客户端 JavaScript 中使用此库。
相关文章:
- React JS:未捕获(在承诺中)语法错误:在位置 0 的 JSON 中意外<令牌
- 如何判断请求/承诺是否需要超过5秒才能完成,angular js
- 因果报应,幻影JS和es6承诺
- Node.js-承诺和锥形语句(if、switch等)-如何构建
- Angular JS承诺和ng重复
- Node JS异步承诺.所有问题
- 处理角度.js承诺错误状态
- Node.JS-Q模块-承诺
- JS承诺:然后和捕获之间有什么区别
- 如何构建模块化的js承诺链
- Phantom.js-如何使用承诺而不是回调
- 这是使用承诺与 Sequelize.js的正确方法吗?
- Node.js承诺使用Q
- JS bluebird承诺错误没有给出任何细节
- 用q.js链接承诺
- 无法获得蓝鸟承诺和猫鼬的 save() 在 node.js 中工作
- 设置蓝鸟承诺分辨率.js最小延迟
- Angular JS承诺,JSON数据和有趣的时间
- 如何编写返回具有正确值的 Q 库承诺的 JS 函数
- 在nodejs中使用Q.js承诺进行循环的正确方法