如何join同步和asynchronous的世界?

我开始与NodeJs和我面临一个问题,我相信很多人可能已经解决了。

我有一个基本的NodeJs Web服务器,如果find一个文件服务文件,或404:

var http = require('http'), url = require('url'), fs = require('fs'), mongoose = require('mongoose'), fileSystem = require('fs'), path = require('path'), util = require('util'), EventEmitter = require('events').EventEmitter; var mimeTypes = { "html": "text/html", "jpeg": "image/jpeg", "jpg": "image/jpeg", "png": "image/png", "js": "text/javascript", "css": "text/css"}; var server; var Schema = mongoose.Schema; mongoose.connect('mongodb://localhost/test'); var db = mongoose.connection; var personneSchema = new Schema({ nom: String, prenom: String }); var Personne = db.model('Personne', personneSchema); var personneAdresseSchema = new Schema({ idPersonne: String, idAdresse: String }); var PersonneAdresse = db.model('PersonneAdresse', personneAdresseSchema); var adresseSchema = new Schema({ ligne1: String, ligne2: String, codePostal: String, ville: String }); var Adresse = db.model('Adresse', adresseSchema); db.on('error', console.error.bind(console, 'connection error:')); db.once('open', function () { server = http.createServer(function (request, response) { if (request.url=='/persons') { console.log('> Persons request'); /* IMPLEMENTATION PROBLEM HERE */ var retour='[]'; retour=retour.substr(0, retour.length-1)+']'; response.writeHead(200, { 'Cache-Control': 'no-cache, must-revalidate', 'Expires': 'Mon, 26 Jul 1997 05:00:00 GMT', 'Content-type': 'application/json' }); response.end(retour); console.log('> end of main function'); return; } var uri = url.parse(request.url).pathname; var filename = path.join(process.cwd(), uri); console.log("> " + filename); fs.exists(filename, function(exists) { if ((!exists) || (fs.lstatSync(filename).isDirectory())) { console.log(">> fichier inexistant : " + filename); response.writeHead(200, {'Content-Type': 'text/plain'}); response.write('404 Not Found\n'); response.end(); // Stopper tout traitement : return; } var mimeType = mimeTypes[path.extname(filename).split(".")[1]]; response.writeHead(200, {'Content-Type':mimeType}); var fileStream = fs.createReadStream(filename); fileStream.pipe(response); }); }); // Listen on port 8000, IP defaults to 127.0.0.1 server.listen(8000); // Put a friendly message on the terminal console.log("Server running at http://127.0.0.1:8000/"); }); 

问题是:在“main”函数结束之前 ,Web服务器需要准备好发送响应。 但是,如果您尝试进行mongoose呼叫,它不是同步的。 如果你把下面的代码放在main函数中:

 Personne.find({}).select('nom prenom').exec(function (err, p) { console.log('> Persons request finished'); }); 

日志显示如下:

 > Persons request > end of main function > Persons request finished 

因此需要填充“响应”的主函数不能用Personne.find({})填充,因为Personne.find({})完成之后 。 处理这个的方法是什么? 我无法在Web上find一个非常简单,自我解释的示例(nodejs + mongoose总是给我解决scheme,无论是单独的nodejs,单独的mongoose,还是使用完整的Web框架,而我只需要一个简单的工作示例)。

数据库调用完成后,您想要执行的任何代码都必须位于数据库调用的callback函数中。 所以你不能只把数据库调用放在你的main函数中 – 你必须把你的main函数中所有需要在数据库调用之后执行的代码移到callback函数中。

如果您希望服务器在您的mongo查询完成后启动,则可以使用callback:

 db.once('open', function () { server = http.createServer(function (request, response) { Personne.find({}).select('nom prenom').exec(function (err, persons) { // Log the result of the query console.log(persons) // After the query is executed, you can use the results anywhere else inside your logic if (request.url=='/persons') { console.log('> Persons request'); /* IMPLEMENTATION PROBLEM HERE */ var retour='[]'; retour=retour.substr(0, retour.length-1)+']'; response.writeHead(200, { 'Cache-Control': 'no-cache, must-revalidate', 'Expires': 'Mon, 26 Jul 1997 05:00:00 GMT', 'Content-type': 'application/json' }); response.end(retour); console.log('> end of main function'); return; } var uri = url.parse(request.url).pathname; var filename = path.join(process.cwd(), uri); console.log("> " + filename); fs.exists(filename, function(exists) { if ((!exists) || (fs.lstatSync(filename).isDirectory())) { console.log(">> fichier inexistant : " + filename); response.writeHead(200, {'Content-Type': 'text/plain'}); response.write('404 Not Found\n'); response.end(); // Stopper tout traitement : return; } var mimeType = mimeTypes[path.extname(filename).split(".")[1]]; response.writeHead(200, {'Content-Type':mimeType}); var fileStream = fs.createReadStream(filename); fileStream.pipe(response); }); }); }); // Listen on port 8000, IP defaults to 127.0.0.1 server.listen(8000); // Put a friendly message on the terminal console.log("Server running at http://127.0.0.1:8000/"); });