如何将所有这些逻辑与javascript Promises混合
How do I mix all this logic with javascript Promises?
我在Node中使用bluebird,而且我对使用Promises还很陌生,尤其是当事情开始超越基础时。
这是我需要使用Promises构建的一个函数,我正在努力找出设置它的最佳方法。在高层,此函数将获取一个模型对象并返回它,从而将任何查询属性转换为其结果集。例如,一个属性的值可以是"query(top5Products)",我们需要查找该命名查询并用该查询的结果替换该值。属性也可以是一个实际的基于字符串的查询(使用RQL,例如"eq(contentType,products)&limit(5,0)")。然后,转换后的模型对象将用于绑定模板。
这是我的伪编码函数,目前是同步的,除了对现有promise返回服务的调用。。。
function resolveQueryPropertiesOnModel(model) {
for (let property in model) {
if (model.hasOwnProperty(property)) {
let queryName = this.getNameOfNamedQuery(model[property]); // will return undefined if the property is not a named query
if (queryName) {
// this property is a named query, so get it from the database
this.getByName(queryName)
.then((queryObject) => {
// if queryObject has a results propery, that's the cached resultset - use it
if (queryObject && queryObject.results) {
model[property] = queryObject.results;
}
else {
// need to resolve the query to get the results
this.resolve(queryObject.query)
.then((queryResults) => {
model[property] = queryResults;
});
}
};
}
else if (this.isQuery(model[property]) { // check to see if this property is an actual query
// resolve the query to get the results
this.resolve(model[property])
.then((queryResults) => {
model[property] = queryResults;
});
}
}
}
// return some sort of promise that will eventually become the converted model,
// with all query properties converted to their resultsets
return ???;
}
当涉及到用逻辑和一些预先存在的承诺进行循环并将它们混合在一起时,我仍然非常生疏。
任何帮助都将不胜感激。
下面是一个使用Bluebird的代码实现,它进行了以下结构更改:
- 运行外部
for
循环并收集已启动的所有promise - 返回嵌套的promise以链接它们,因此顶级promise将指示何时在该链中完成所有操作
- 将任何新承诺收集到
promises
阵列中 - 使用
Promise.all(promises)
跟踪所有异步promise操作何时完成并返回 - 您的结果似乎是修改
models
对象的副作用,因此不会通过promise返回显式值。您可以使用返回的promise来知道所有异步操作何时完成,然后可以检查model
对象以获取结果
代码:
function resolveQueryPropertiesOnModel(model) {
const promises = [];
for (let property in model) {
let p;
if (model.hasOwnProperty(property)) {
let queryName = this.getNameOfNamedQuery(model[property]); // will return undefined if the property is not a named query
if (queryName) {
// this property is a named query, so get it from the database
p = this.getByName(queryName).then((queryObject) => {
// if queryObject has a results propery, that's the cached resultset - use it
if (queryObject && queryObject.results) {
model[property] = queryObject.results;
} else {
// need to resolve the query to get the results
return this.resolve(queryObject.query).then((queryResults) => {
model[property] = queryResults;
});
}
};
} else if (this.isQuery(model[property]) { // check to see if this property is an actual query
// resolve the query to get the results
p = this.resolve(model[property]).then((queryResults) => {
model[property] = queryResults;
});
}
}
// if we started a new promise, then push it into the array
if (p) {
promises.push(p);
}
}
return Promise.all(promises);
}
这就是我解决它的方法。
- 如果所有的承诺都得到了解决,那么q.all()就会得到解决。每个promise都是处理的模型中的一个属性
- 对于每个属性(我会使用像lodash和_.reduce这样的库,但如果你愿意,你可以使用hasOwnProperty)。无论如何,foreach属性,resolveModelProperty函数返回一个决定属性命运的promise,如果有查询名称,则获取它,如果没有并且有查询,则解析它,如果不是,则不更改属性
- 对于helper函数,resolveByName和resolveQuery将处理缓存和未缓存查询的情况
function resolveQueryPropertiesOnModel(model) {
const promises = [],
resolveQuery = toBeResolved => this.resolve(toBeResolved),
resolveByName = queryName => this.getByName(queryName)
.then(queryObject => queryObject && queryObject.results
? queryObject.results : resolveQuery(queryObject.query)),
resolveModelProperty = (modelProperty) => {
const queryName = this.getNameOfNamedQuery(modelProperty);
return queryName ? resolveByName(queryName) :
this.isQuery(modelProperty) ? resolveQuery(modelProperty):
modelProperty;
};
for(let property in model)
if( model.hasOwnProperty(property)
promises.push(resolveModelProperty(model[property])
.then(result=> model[property]=result));
return q.all(promises);
}
相关文章:
- 为什么javascript ES6 Promises在解析后继续执行
- 解析javascript对象中的Promises
- JavaScript Promises and setTimeout
- JavaScript中的异步函数递归和Bluebird Promises
- Javascript/Parse.com - Promises, Calling response.success()
- JavaScript:用Promises调用递归函数
- 使用Promises加载带有JavaScript的jQuery
- 如何在解决所有javascript ES6 Promises后运行
- Javascript Promises with FileReader()
- Javascript, Node, Promises, and recursion
- 在JavaScript中使用Memoization和Promises+Deferrends缓存从AJAX加载到本地变量的
- 在没有线程的情况下,如何在Javascript中实现Promises ?
- JavaScript Promises
- Javascript Promises (Q)不会等待下一个问题被解决
- 如何使用Jasmine.js对Javascript Promises进行单元测试?
- 当JavaScript是单线程的时候,Promises是如何工作的?
- done()和Javascript promises中的catch()一样(使用sequelize和bluebird)吗
- 如何使用javascript Promises来更新mongodb中的多个文档
- 如何将所有这些逻辑与javascript Promises混合
- ElasticSearch JavaScript Promises