最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
解决nodejs搭配express、mongoose异步流程问题解决办法
时间:2022-06-25 18:28:32 编辑:袖梨 来源:一聚教程网
1、引子
在 node 端,express 的 HTTP 启动和 mongoose 的 mongodb 连接都是异步的,因此会遇到,打开网站时,数据库还没有连上,导致查询错误,或者遇到数据库已经连接上了,但 HTTP 服务已经启动失败了。
还有更复杂一点的使用场景:首先链接数据库,然后是中间件(比如查询固定配置,如网站标题、管理员信息、oauth配置等不需要变更的配置,但需要存储再数据库的配置,因为源代码是公开在 github 上的,目前作者的需求就是这样的),最后启动 HTTP 服务器。
关于这个启动过程,虽然有些麻烦,但还是在 node 端异步情况下,经常出现的。比如(此处仅为示例),查询3个用户,然后分别查询这个3个用户发布文章的数量,以及这3个用户关注的主题。看上去是不是很复杂?
以上,如果你觉得很简单的话,那么可以到此为止了。
2、使用howdo来处理异步串行
2.1、express + mongoose
如果启动只需要这两样的话,那么不需要担心,直接这样:
var howdo = require('howdo');
/**
* 启动 HTTP 服务
* @param callback {Function} 回调
*/
var express = function (callback) {
var app = require('express')();
app.listen(80, callback);
};
/**
* 连接数据库
* @param callback {Function} 回调
*/
var mongoose = function (callback) {
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost:27017/some-table');
mongoose.connection.on('connected', callback);
mongoose.connection.on('error', callback);
mongoose.connection.on('disconnected', callback);
};
/**
* 异步并行
*/
howdo.task(express).task(mongoose).together(function (err) {
if (err) {
console.error(err);
process.exit(-1);
}
console.log('');
console.log('#########################################################');
console.log('http server running at 80');
console.log('#########################################################');
console.log('');
});
2.2、express+mongoose+middleware
源码如下(很直观):
var howdo = require('howdo');
/**
* 实例化 express
* @param callback {Function} 回调
*/
var express = function (callback) {
var app = require('express')();
callback(null, app);
};
/**
* 连接数据库
* @param callback {Function} 回调
* @param app {Object} express 实例
*/
var mongoose = function (callback, app) {
var mongoose = require('mongoose');
var proxyCallback = function (err) {
callback.call(global, err, next, app);
};
mongoose.connect('mongodb://localhost:27017/some-table');
mongoose.connection.on('connected', proxyCallback);
mongoose.connection.on('error', proxyCallback);
mongoose.connection.on('disconnected', proxyCallback);
};
/**
* 中间件
* @param callback {Function} 回调
* @param app {Object} express 实例
*/
var middleware = function (callback, app) {
var someModel = require('path/to/model');
someModel.getConfig(function (err, configs) {
if (err) {
return callback(err);
}
app.locals._configs = configs;
callback(err, app);
});
};
/**
* 启动 HTTP 服务
* @param callback {Function} 回调
* @param app {Object} express 实例
*/
var http = function (callback, app) {
app.listen(80, callback);
}
/**
* 异步串行
*/
howdo
.task(express)
.task(mongoose)
.task(middleware)
.task(http)
.follow(function (err) {
if (err) {
console.error(err);
process.exit(-1);
}
console.log('');
console.log('#########################################################');
console.log('http server running at 80');
console.log('#########################################################');
console.log('');
});
3、数据库查询综合
看起来比较复杂:
var howdo = require('howdo');
var userMode = require('path/to/user-model');
var postMode = require('path/to/post-model');
var followMode = require('path/to/follow-model');
/**
* 查询 3 个用户
* @param callback {Function} 完成回调
*/
var getThreeUsers = function (callback) {
userMode.getUsers(10, callback);
};
/**
* 查询 1 个用户的文章信息
* @param user {Object} 用户信息
* @param callback {Function} 完成回调
*/
var getUserPosts = function (user, callback) {
postMode.getUserPosts(user, callback);
};
/**
* 查询 1 个用户的关注信息
* @param user {Object} 用户信息
* @param callback {Function} 完成回调
*/
var getUserFollows = function (user, callback) {
followMode.getUserFollows(user, callback);
};
/**
* 读取所有用户的文章信息
* @param users {Array} 用户列表数组
* @param callback {Function} 完成回调
*/
var getUsersPosts = function (users, callback) {
// 读取用户的文章信息
howdo.each(users, function (index, user, done) {
getUserPosts(user, done);
}).together(function (err, user0Posts, user1Posts, user2Posts) {
if (err) {
return callback(err);
}
var postsList = Array.prototype.slice.call(arguments, 1);
// 写入用户的文章信息
postsList.forEach(function (posts, index) {
users[index].posts = posts;
});
callback(null, users);
});
};
/**
* 读取所有用户的关注信息
* @param users {Array} 用户列表数组
* @param callback {Function} 完成回调
*/
var getUsersFollows = function (users, callback) {
// 读取用户的关注信息
howdo.each(users, function (index, user, done) {
getUserFollows(user, done);
}).together(function (err, user0Follows, user1Follows, user2Follows) {
if (err) {
return callback(err);
}
var followsList = Array.prototype.slice.call(arguments, 1);
// 写入用户的文章信息
followsList.forEach(function (follows, index) {
users[index].follows = follows;
});
callback(null, users);
});
};
howdo
.task(getThreeUsers)
.task(function (next, users) {
howdo
.task(function (done) {
getUserPosts(users, done);
})
.task(function (done) {
getUsersFollows(users, done);
})
// 异步并行
.together(next);
})
// 异步并行
.follow(function (err, users) {
if (err) {
console.error(err);
process.exit(-1);
}
// 组装好后的 users 对象
console.log(users);
});
相关文章
- 第五人格11.22共研服有什么更新 11月22日共研服更新内容介绍 11-21
- 原神恰斯卡怎么培养 11-21
- 无期迷途四星装束是谁 11-21
- 王者荣耀帝丹高中校服怎么获得 11-21
- 光遇姆明季后续版本怎么玩 11-21
- 《潜行者2:切尔诺贝利之心》使用手电筒方法介绍 11-21