如何将所有这些逻辑与 javascript Promises 混合?
How do I mix all this logic with javascript Promises?
我在 Node 中使用 bluebird,但我对使用 Promises 还是很陌生,尤其是当事情开始超出基础时。
这是我需要使用 Promises 构建的函数,我正在努力找出设置它的最佳方法。在高层次上,这个函数将采用一个模型对象,然后 return 它,将任何查询属性转换为它们的结果集。例如,属性 的值可以是 "query(top5Products)",我们需要查找该命名查询并将该值替换为该查询的结果。属性也可以是一个实际的基于字符串的查询(使用 RQL,例如 "eq(contentType,products)&&limit(5,0)")这个转换后的模型对象将用于绑定模板。
这是我的伪代码函数,当前是同步的,除了调用现有的 promise-returning 服务...
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 ???;
}
在使用逻辑循环和一些预先存在的承诺并将它们混合在一起时,我仍然很生疏。
任何帮助将不胜感激。
这就是我要解决的方法。
- a q.all() 如果所有承诺都得到解决,则将得到解决。每个承诺都是处理模型中的一个 属性。
- 每个 属性(我会使用像 lodash 和 _.reduce 这样的库,但如果你愿意,你可以使用 hasOwnProperty)。 anyway,foreach属性,resolveModelProperty函数returns一个决定命运的promise属性,如果有query name,获取,如果没有且有query,resolve , 如果不是,请不要更改 属性.
- 对于辅助函数,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);
}
下面是使用 Bluebird 进行这些结构更改的代码实现:
- 运行外部
for
循环并收集所有已启动的承诺
- Returns 嵌套的 promise 将它们链接在一起,因此顶级 promise 将指示该链中的所有内容何时完成
- 将所有新承诺收集到
promises
数组中
- 使用
Promise.all(promises)
跟踪所有异步承诺操作何时完成以及 returns 那个。
- 您的结果似乎是修改
models
对象的副作用,因此不会通过承诺返回明确的值。您可以使用返回的承诺来了解所有异步操作何时完成,然后您可以检查 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);
}
我在 Node 中使用 bluebird,但我对使用 Promises 还是很陌生,尤其是当事情开始超出基础时。
这是我需要使用 Promises 构建的函数,我正在努力找出设置它的最佳方法。在高层次上,这个函数将采用一个模型对象,然后 return 它,将任何查询属性转换为它们的结果集。例如,属性 的值可以是 "query(top5Products)",我们需要查找该命名查询并将该值替换为该查询的结果。属性也可以是一个实际的基于字符串的查询(使用 RQL,例如 "eq(contentType,products)&&limit(5,0)")这个转换后的模型对象将用于绑定模板。
这是我的伪代码函数,当前是同步的,除了调用现有的 promise-returning 服务...
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 ???;
}
在使用逻辑循环和一些预先存在的承诺并将它们混合在一起时,我仍然很生疏。
任何帮助将不胜感激。
这就是我要解决的方法。
- a q.all() 如果所有承诺都得到解决,则将得到解决。每个承诺都是处理模型中的一个 属性。
- 每个 属性(我会使用像 lodash 和 _.reduce 这样的库,但如果你愿意,你可以使用 hasOwnProperty)。 anyway,foreach属性,resolveModelProperty函数returns一个决定命运的promise属性,如果有query name,获取,如果没有且有query,resolve , 如果不是,请不要更改 属性.
- 对于辅助函数,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);
}
下面是使用 Bluebird 进行这些结构更改的代码实现:
- 运行外部
for
循环并收集所有已启动的承诺 - Returns 嵌套的 promise 将它们链接在一起,因此顶级 promise 将指示该链中的所有内容何时完成
- 将所有新承诺收集到
promises
数组中 - 使用
Promise.all(promises)
跟踪所有异步承诺操作何时完成以及 returns 那个。 - 您的结果似乎是修改
models
对象的副作用,因此不会通过承诺返回明确的值。您可以使用返回的承诺来了解所有异步操作何时完成,然后您可以检查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);
}