我是node.js的新手,我很难理解基于事件的异步编程的概念。 我正在实现一个宁静的API Web服务,因此请考虑以下简单的(同步!)API方法addStuff(),它将方法插入到Elasticsearch数据库中:
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 });
}
);
}
至少,我还没有找到更好的解决方案。我试图找出如何使对数据库的异步调用成为同步调用,但基本上每个人都在说:只是不要这样做。 那么,如果我不想在测试完成后又想重构所有东西并对其进行重构,又该不再需要额外的数据库检查了,我该怎么做呢?
哦...,如果您对我的问题不满意,请发表评论。 因为我感觉很多人都在为这个问题而苦恼,但是我还没有找到满意的答案。
答案 0 :(得分:1)
您可以使用async \ await语法使代码可读。 例如,您可以执行以下操作:
async function getStuffById(){
//return true or false; }
在“添加内容”功能中,您可以编写:
if ( await getStuffById() ){
//do some more stuff }
请注意,您还必须使“添加内容”异步,以便使用等待语法。
有关异步\ await的更多信息,请参见here