我正在使用Express应用。在启动时,它连接到Redis服务器和PostgreSQL服务器。我想等待两个连接成功后再启动Express服务器。现在,如果我只等待one回调,则可以在该回调中启动Express服务器。但是,在等待多个异步操作时,如何最好地做到这一点?我是新来的。有没有做这种事情的惯用模式?也许将诺言分组在一起或..?
承诺就是您想要的。
您可以在诺言数组上使用.all()
以等待它们全部完成。您没有提到正在使用的Promise库,但是它相当通用。这是Bluebird文档:https://github.com/petkaantonov/bluebird/blob/master/API.md#all---promise
承诺可能是解决此问题的惯用方式。您将不得不“保证”返回回调的函数,以将其转换为可返回并解析承诺的函数,但是Promise.all()
可以正常工作。我个人将Bluebird用于我的nodejs开发,并定期使使用异步回调的现有功能或整个模块有问题。
[如果您没有使用其他可以承诺未承诺功能的库,那么您也可以只使用一个计数器来跟踪所有回调何时完成。这是“老式”的处理方式,但是也很好用。这样的操作是这样的:
function setup(fn) {
// initialize counter to number of async operations
var counter = 3;
function checkDone() {
--counter;
if (counter <= 0) {
fn();
}
}
firstAsyncFunction(...., checkDone);
secondAsyncFunction(...., checkDone);
thirdAsyncFunction(...., checkDone);
}
setup(function() {
// this will get called when all the initial async operations are done
});
就我而言,在启动我的应用程序之前,我需要等待mongodb和redis连接。下面是我的实现。
注意:我正在使用Koa,但是相同的实现也应该与Express.js一起使用。
redis-connection.ts文件
import redis from 'redis'
const redisConnection = (app) => {
const client = redis.createClient({ url:'connectionString' })
client.set('hello', 'world', (err)=> {
if(err) {
throw err
}
app.emit('redis-connected')
})
}
export default redisConnection
db-connection.ts文件
import mongoose from 'mongoose';
const dbConnection = (app) => {
mongoose.connect('connectionString', {
useNewUrlParser: true,
useCreateIndex: true,
useUnifiedTopology: true,
useFindAndModify: false
});
mongoose.connection.once('open', () => {
app.emit('db-connected');
});
return mongoose;
};
export default dbConnection;
app.ts文件
'use strict'
import Koa from 'koa'
import dbConnection from './config/connections/db-connection'
import redisConnection from './config/connections/redis-connection'
const app: Koa.DefaultState = new Koa()
// Perform db connection
dbConnection(app)
// Perform redis connection
redisConnection(app)
export default app
index.ts文件
import app from './app'
const port = 3000
app.on('db-connected', () => {
app.on('redis-connected', () => {
app.listen(port, () => {
console.log(`Server running on port ${port}`)
})
})
})