我有一个我正在创建的规则引擎的代码
getSKULine = (s, priceList) ->
rdb.getDiscountMap(s, priceList)
.then (result) ->
console.log result
if result.cdLine is "T" and result.cdOver is "F" then result else null
exports.getRules = (user) ->
if !user
Promise.resolve null
else
priceList = user.company.opera.terms.priceList
territory = user.company.opera.account.territory
country = user.company.country
emailId = user.emailId
account = user.company._id
trade_sector = user.company.trade_sector
discountCache = {}
cond = {
'status': 'published'
'type': 'price'
"to" : { "$gte" : Date.now() }
"unselPriceLists": { "$nin": [ priceList ] }
"unselReps": { "$nin": [ territory ] }
"unselCountries": { "$nin": [ country ] }
"unselAccounts": { "$nin": [ account ] }
"unselCompanyTypes": { "$nin": [ trade_sector ] }
}
Rule.findAllPr(cond)
.then (rules) ->
_.zipObject rules.map (r) ->
skus = _.zipObject(r.skus.map((s) ->
if getSKULine(s, priceList)
[
s
r.discount
]
else null
))
extended = _.extend(discountCache, skus)
.then (skus) ->
discountCache
行if getSKULine(s, priceList)
中的我正在检查具有
条目的redis缓存{ sku: 'SA61-MNA',
priceList: 'DISTSD',
quantity1: 1,
quantity2: 10,
quantity3: 50,
price1: 263,
price2: 228,
price3: 208,
cdLine: 'T',
cdOver: 'T',
cdFundec: 2 }
{ sku: 'SA61-MPL',
priceList: 'DISTSD',
quantity1: 1,
quantity2: 10,
quantity3: 50,
price1: 263,
price2: 228,
price3: 208,
cdLine: 'T',
cdOver: 'T',
cdFundec: 2 }
我想只返回一个对象,其中cdLine是' T'和cdOver是' F'但它似乎不起作用,因为我的discountCache对象仍包含这些行?
我缺少什么,非常感谢任何建议
答案 0 :(得分:0)
我相信你会想要使用Array.prototype.reduce
代替地图,这样你就可以有条件地添加getSKULine
返回的结果。像这样:
skus = _.zipObject (r.skus.reduce(((accum, s) ->
obj = getSKULine(s, priceList)
if obj? and obj.cdLine is 'T' and obj.cdOver is 'F'
accum.push([s, r.discount)
accum), [])
现在您正在使用reduce
代替map
,您不需要使用lodash函数来转换结果:
skus = r.skus.reduce(((accum, s) ->
obj = getSKULine(s, priceList)
if obj? and obj.cdLine is 'T' and obj.cdOver is 'F'
accum[s] = r.discount
accum), {})
很抱歉只是意识到getSKULine
会返回一个Promise而不是一个对象。这就是为什么您的原始代码不起作用的原因:您正在混合同步和异步代码。由于函数返回Promise,结果将始终是真实的,getSKULine
中的条件过滤不会做任何事情。实际上,整个功能是不必要的。你需要做这样的事情:
#map over the skus to get an array of Promises, use Promise.all
#to convert to a Promise of an array of objects from the Redis
#cache
skuLines = Promise.all(r.skus.map((s) -> rdb.getDiscountMap(s, priceList)));
result = skuLines.then((arr) -> arr.reduce(((accum, obj, i) ->
#grabbing the original sku
s = r.skus[i]
#moved the filtering from getSKULine to here
if obj? obj.cdLine is 'T' and obj.cdOver is 'F' then accum[s] = r.discount
accum), {}))
要从结果中获取结束对象,您需要在其上调用then
。像result.then((res) -> doStuff(res))
这样的东西。请记住,您无法取消选择'一个Promise,你总是需要调用then
方法来获取里面的值。原来的getSKULines
出了什么问题,你认为你正在返回null
,但是由于then
自动将结果包装到另一个Promise中,你实际上是在返回一个 Promise null
。