我是node.js的新手,我很难理解基于事件的异步编程的概念。我正在实现一个宁静的API Web服务,所以请考虑以下简单(同步!)API方法addStuff(),它将内容插入到elasticsearch db:
var client = new elasticsearch.Client({ host: 'localhost:9200' });
function indexStuff(stuff) {
return client.index({
index: 'test_idx',
type: 'test',
id: stuff.id,
body: stuff
});
}
function addStuff(req, res, next) {
let stuff = processRequest(req);
indexStuff(stuff).then(
function (body) {
return true;
},
function (error) {
res.status(error.status).send({ message: error.message });
}
);
}
到现在为止还挺好。现在在测试期间我想避免将现有的东西插入数据库。所以我想添加类似的东西:
function stuffAlreadyInDB(id) {
... // returns true/false
}
function addStuff(req, res, next) {
if (stuffAlreadyInDB(req.id))
{
res.status(409).send({ message: 'stuff with id ' + req.id + ' already in DB' });
return;
}
var stuff = processRequest(req);
...
}
不幸的是,对elasticsearch db的调用是异步的,这意味着,我不能只在同步函数中返回一个布尔值。相反,我必须将整个shabang重构为某种东西(可能不太容易阅读),如下所示:
function getStuffByID(id) {
return client.get({
id: id,
index: 'test_idx',
type: 'test',
ignore: 404
});
}
function addStuff(req, res, next) {
getStuffByID(req.id).then(
function(resp) {
if (resp.found) {
res.status(409).send({ message: 'stuff with id ' + req.id + ' already in DB' });
return;
}
else {
var stuff = processRequest(req);
indexStuff(stuff).then(
function (body) {
res.writeHead(200, {'Content-Type': 'application/json' });
res.end();
},
function (error) {
res.status(error.status).send({ message: error.message });
}
);
}
},
function(error) {
res.status(error.status).send({ message: error.message });
}
);
}
至少,我还没有找到更好的解决方案。我试图找出如何对db进行异步调用同步调用,但基本上每个人都说:只是不要这样做。那么,如果我不想重构所有内容并且当我完成测试并且不再需要这个额外的数据库检查时,我应该怎么做呢?
哦......如果你向我的问题投票:请留言你为什么这样做。因为我觉得很多人都在努力解决这个问题,但我还没有找到令人满意的答案。
您可以使用async \ await语法来使您的代码可读。例如,你可以这样做:
async function getStuffById(){
//return true or false; }
在“添加东西”功能中你可以写:
if ( await getStuffById() ){
//do some more stuff }
请注意,为了使用等待语法,您还必须使“添加内容”异步。
更多关于async \ await可以找到here