2017-06-05 42 views
1

我试图撰写的一些功能整合在一起:如何管道功能,当承诺在中间检查授权?

compose = (...fns) => fns.reduce((f, g) => (...args) => f(g(...args))); 

checkAuthorization返回检查,如果用户被授权的承诺。 buildParams收到someRequestData,并将结果传送至searchItem

checkAuthorization() 
     .then(() => { 
      compose(
       searchItem, 
       buildParams 
      )(someRequestData) 
    }, (e) => { 
     handleError(e) 
    }) 

我认为这是美好的,但我希望有一个更优雅的外观为便于阅读,是这样的:

compose(
     searchItem, 
     checkAuthorization 
     buildParams 
    )(someRequestData) 

所以会发生什么事是: 1)建立PARAMS 2)checkAuth 3)搜索项

有什么建议吗?

回答

1

不,这是不可能的,因为checkAuthorisation没有收到并通过params。即使你会重写它来做到这一点,它仍然会很奇怪,并且读者会认为你正在构建授权应该被检查的params。所以不要这样做 - 你有一个非线性流动,并试图强制它进入一些线性组合是不行的。

顺便说一句,我会建议避免compose当你调用该函数立即反正:

checkAuthorization().then(() => 
    searchItem(buildParams(someRequestData)) 
, e => 
    handleError(e) 
); 

也许

checkAuthorization().then(compose(searchItem, buildParams,()=>someRequestData) 
         , handleError); //    ^^^^ "const" 
+0

是啊,这就是我的想法。感谢您的建议。 – Chen

+0

@Bergi,请看我的答案。你怎么看?如果您有任何想法,我该如何跟踪可能的“拒绝”状态? – wostex

1

这里有一个作曲家同时处理同步功能和承诺。看起来它工作正常维持秩序:

// Async pipe try. Pass functions left to right 
 
const pipePromises = (...fns) => x => fns.reduce((p, fn) => p.then(fn), Promise.resolve(x)); 
 
    
 
// functions for the test 
 
const me = x => new Promise(function(resolve, reject) { 
 
    setTimeout(() => resolve(x), 10) 
 
}) 
 

 
const double = x => new Promise(function(resolve, reject) { 
 
    setTimeout(() => resolve(x * 2), 30) 
 
}) 
 

 
const inc = x => new Promise(function(resolve, reject) { 
 
    setTimeout(() => resolve(x + 1), 400) 
 
}) 
 

 
const log = x => { console.log('log: ', x); return x } 
 

 
const syncTriple = x => x * 3; // sync function 
 

 
// let's call our chain 
 
pipePromises( 
 
    me, log, // 3 
 
    double, log, // 6 
 
    syncTriple, log, // 18 -- SYNC 
 
    inc, log, // 19 
 
    double, log, // 38 
 
    inc, log, // 39 
 
    syncTriple, log, // 117 -- SYNC 
 
    inc, log // 118 
 
)(3) // 3

+0

我会说'log'应该同步。是的,虽然你可以建立这样的功能(和[其他人也已经完成了这个功能]),但我认为它不适用于这个问题。 – Bergi

+0

永远不要像你所做的那样将承诺与非承诺区分开来(可怕的'.constructor.name'检查在大多数实现中都不起作用)。您应该使用'Promise.resolve(v)'并且始终将其视为异步。对于构成函数,你知道'v'是一个承诺。所以'函数composePromises(... fns){return v => fns.reduceRight((p,fn)=> p.then(fn),Promise.resolve(v)); }' – Bergi

+0

谢谢@Bergi,这样好多了。 – wostex