Javascript脱离回调地狱,利用生成器串行处理业务逻辑

时间:2022-11-20 20:01:18


这里给出一个例子,这个例子使用 node 作为 web 后台,处理用户添加,添加之前先检查数据库,查看该用户是否已经存在,如果存在汇报错误后直接退出,如果该用户不存在,再次操作数据库插入新用户。

expressInst.post('/cgi-bin/useradd', function (req, res) {
var it = postUserAdd(req, res); // 创建生成器实例
it.next(); // 启动生成器实例
it.next(it); // 将生成器实例传入自身,postUserAdd 要将生成器实例传入数据库操作的回调函数
});

function *postUserAdd(req, res) {
var it = yield; // 获取生成器实例,即自身
var userList = [];
var err, result;

// 调用数据库查找操作,回调函数中恢复生成器实例的执行
db.collection('user').findOne({username: req.body.username}, function (err, result) {
it.next([err, result]); // 恢复生成器实例的执行,返回的多个参数需要组合成数组的形式
});

[err, result] = yield; // 生成器在此处挂起生成器实例,直到数据库回调函数恢复生成器实例的执行

// 对数据库的查询操作结果进行处理
if(err) {
res.status(500).end();
return;
}

if(result) {
res.status(400).end();
return;
}

// 调用数据库插入操作,回调函数中恢复生成器实例的执行
db.collection('user').insertOne({username: req.body.username}, function (err, result) {
it.next([err, result]); // 恢复生成器实例的执行,返回的多个参数需要组合成数组的形式
});

[err, result] = yield; // 生成器在此处挂起生成器实例,直到数据库回调函数恢复生成器实例的执行

// 对数据库的插入操作结果进行处理
if(err || !result) {
res.status(500).end();
return;
}

res.end();
}

用上生成器后,业务逻辑的执行还是异步的,但是代码的编写是同步的,非常直观,这简化了串行业务逻辑的处理,又有异步执行的高性能。