我刚开始在Node / Express中使用ElasticSearch,而不是经验丰富的JavaScript / ES6开发人员,我对Promises感到有点困惑。
情况如下:我收到一个包含一个或多个查询参数的请求。这些需要转换为ElasticSearch查询。一些查询参数可以很容易地在(部分)ElasticSearch查询中进行转换,有些则需要更长时间运行的任务,例如查询另一个ElasticSearch索引。
这就是我现在在服务层中的内容:
const find = function(q) {
return generateElasticQuery(q).then(function(elasticQuery) {
return model.find(elasticQuery)
})
}
其中q
包含来自GET请求的查询参数。
在generateElasticQuery
中,我启动一个查询对象,然后使用许多函数对其进行修改:
const generateElasticQuery = function(q) {
let elasticQuery = { "term": {} }
return Promise.all([
processParameterA(q, elasticQuery),
processParameterB(q, elasticQuery)
]).then(function() {
return elasticQuery
})
}
这些功能看起来像这样:
const processParameterA = function(q, elasticQuery) {
return new Promise(function(resolve, reject) {
if (q.parameterA) {
someOtherAsyncTask(q.parameterA).then(function(res) {
// modify elasticQuery
resolve()
})
} else {
resolve()
}
})
}
const processParameterB = function(q, elasticQuery) {
return new Promise(function(resolve, reject) {
// nothing to be done for now
resolve()
})
}
这一切似乎都有效,但感觉不太对劲。这种情况有更好的方法吗?
因此,在Bergi的评论之后,我首先对此进行了重构:
const processParameterA = function(q) {
return new Promise(function(resolve, reject) {
if (q.parameterA) {
someOtherAsyncTask(q.parameterA).then(function(res) {
resolve(res)
})
} else {
resolve()
}
})
}
const generateElasticQuery = function(q) {
return Promise.all([
processParameterA(q),
processParameterB(q)
]).then(function(results) {
let parameterAResult = results[0]
let parameterBResult = results[1]
let elasticQuery = { "term": {} }
// modify elasticQuery
return elasticQuery
})
}
然后:
const generateElasticQuery = function(q) {
let tasks = []
if (q.parameterA) {
tasks[0] = someOtherAsyncTask(q.parameterA)
}
return Promise.all(tasks).then(function(results) {
let parameterAResult = results[0]
let elasticQuery = { "term": {} }
// modify elasticQuery
return elasticQuery
})
}