诺基亚在NodeJS

我试图将一些callback转换为使用蓝鸟或Q的NodeJS的诺言,但我没有成功。 任何人都可以很好,给我一个例子如何将上面的代码转换为承诺?

提前致谢

阿德里安

function httpResponse(request, response) { fs.readFile('views/main.ejs', 'utf-8', function readFile(error, file) { if (error) { response.writeHead(200, {"Content-Type": "text/plain"}); response.write('EJS ERROR'); response.end(); } else { // get domains data from db needed for main page dbHandle.queryDB({}, "domains", function dbQueryDB(error, result) { var ejsData = {name: "Cav"}; if (error) { response.write('DB ERROR'); response.end(); } else { ejsData.domains = result; // get machine type data from db needed for main page dbHandle.queryDB({}, "type", function dbQueryDB(error, result) { if (error) { response.write('DB ERROR'); response.end(); } else { ejsData.type = result; //respond index.html response.writeHead(200, {"Content-Type": "text/html"}); response.end(ejs.render(file, ejsData)); } }); } }); } }); } 

使用bluebird ,看看promisification部分 。

基本上你会做这样的事情:

 var fs = require("fs"); Promise.promisifyAll(fs); Promise.promisifyAll(dbHandle); //do this globally if it is global, not every request! 

那么你的代码会是这样的:

  function httpResponse(request, response) { fs.readFileAsync('views/main.ejs', 'utf-8') //Special catch only for EJS errors. ONce past this point in the chain, will not hit again. .then( function(file){ return dbHandle.queryDBAsync({}, "domains"); } ) .then( function(domains){ ejsData.domains = domains; return dbHandle.queryDBAsync({}, "type"); }) .then( function( types ){ ejsData.type = types; response.writeHead(200, {"Content-Type": "text/html"}); response.end(ejs.render(file, ejsData)); }) .catch( function(error){ response.writeHead(200, {"Content-Type": "text/plain"}); response.write('EJS ERROR'); //or DB errors, add some handling if the error message is important response.end(); }); } 

我把这些连在一起,以保持代码更加平坦。 你也可以嵌套承诺。 但是Promisification是去build立图书馆的途径。

编辑要保持file在范围内,请尝试像这样的Promise设置。 注意嵌套的Promise。

 function httpResponse(request, response) { fs.readFileAsync('views/main.ejs', 'utf-8') //Special catch only for EJS errors. ONce past this point in the chain, will not hit again. .then( function(file){ return dbHandle.queryDBAsync({}, "domains") .then( function(domains){ ejsData.domains = domains; return dbHandle.queryDBAsync({}, "type"); }) .then( function( types ){ ejsData.type = types; response.writeHead(200, {"Content-Type": "text/html"}); response.end(ejs.render(file, ejsData)); }) .catch( function(error){ response.writeHead(200, {"Content-Type": "text/plain"}); response.write('EJS ERROR'); //or DB errors, add some handling if the error message is important response.end(); }); } 

另一种方法是跟踪Promise链之外的filevariables。 当返回readFileAsync ,将result存储到file (即声明为独立file ),然后可以稍后使用它。