当中间的承诺中的承诺检查授权时,如何管道功能?
how to pipe functions, when a promise in the promise in the middle checks authorization?
我正在尝试将一些函数组合在一起:
compose = (...fns) => fns.reduce((f, g) => (...args) => f(g(...args)));
checkAuthorization
returns 检查用户是否被授权的承诺。
buildParams
接收 someRequestData
,并将结果通过管道传递给 searchItem
。
checkAuthorization()
.then(() => {
compose(
searchItem,
buildParams
)(someRequestData)
}, (e) => {
handleError(e)
})
我觉得还可以,但我希望有一个更优雅的外观以提高可读性,例如:
compose(
searchItem,
checkAuthorization
buildParams
)(someRequestData)
所以会发生什么:
1)构建参数
2)检查授权
3) 搜索项目
有什么建议吗?
不,那是不可能的,因为 checkAuthorisation
不接收和传递参数。即使你会重写它来做到这一点,它仍然会很奇怪并且 reader 会假设你正在构建应该检查其授权的参数。所以不要那样做 - 你有一个非线性流,试图强迫它进入某种线性组合是不好的。
顺便说一句,我建议您在立即调用该函数时避免 compose
:
checkAuthorization().then(() =>
searchItem(buildParams(someRequestData))
, e =>
handleError(e)
);
或者也许
checkAuthorization().then( compose(searchItem, buildParams, ()=>someRequestData)
, handleError ); // ^^^^ "const"
这是一个用于处理同步功能和 Promises 的组合器。看起来它可以正常维护订单:
// 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
我刚刚制作了一个 npm module 来处理优雅的 Promise
构图。
它仍处于早期阶段,但欢迎您检查代码并根据您的需要和标准对其进行更改。
基本上它提供了两种可能满足您需求的方法:
合并
使用 Promise.combine({...})
,您可以通过为对象提供一系列返回 Promises 的函数并接受先前函数的结果作为输入来组合多个 Promises,如下所示:
Promise.combine({
item: () => searchItem,
auth: ({item}) => checkAuth,
params: ({item, auth}) => buildParams
}).then(({item, auth, params}) => {
// here you can do what you need
})
减少
使用 Promise.reduce([...])
,您可以将 Promise 链接到一个返回 Promise 的函数数组中,并接受先前执行的 Promise 的输出作为输入:
Promise.reduce([
() => searchItem,
(item) => checkAuth,
(auth) => buildParams
]).then((params) => {
// here you can do what you need
})
请注意,在这种情况下,您将无法访问 .then()
函数中的 item
,但您始终可以编写 checkAuth
Promise 的结果,以便通过item
下游也是:
Promise.reduce([
() => searchItem,
(item) => checkAuth.then((auth) => {
return {auth, item}
}),
({auth, item}) => buildParams.then((params) => {
return {params, item}
}),
]).then(({params, item}) => {
// here you can do what you need
})
输入
您还可以像这样从请求中添加一些输入数据:
Promise.reduce([
(requestData) => searchItem,
(item) => checkAuth,
(auth) => buildParams
], requestData).then((params) => {
// here you can do what you need
})
看到我将 requestData
作为 Promise.reduce([...], requestData)
的第二个参数传递,它作为参数传递给第一个函数。
Here you can see the functions code.
希望这会有所帮助。
我正在尝试将一些函数组合在一起:
compose = (...fns) => fns.reduce((f, g) => (...args) => f(g(...args)));
checkAuthorization
returns 检查用户是否被授权的承诺。
buildParams
接收 someRequestData
,并将结果通过管道传递给 searchItem
。
checkAuthorization()
.then(() => {
compose(
searchItem,
buildParams
)(someRequestData)
}, (e) => {
handleError(e)
})
我觉得还可以,但我希望有一个更优雅的外观以提高可读性,例如:
compose(
searchItem,
checkAuthorization
buildParams
)(someRequestData)
所以会发生什么: 1)构建参数 2)检查授权 3) 搜索项目
有什么建议吗?
不,那是不可能的,因为 checkAuthorisation
不接收和传递参数。即使你会重写它来做到这一点,它仍然会很奇怪并且 reader 会假设你正在构建应该检查其授权的参数。所以不要那样做 - 你有一个非线性流,试图强迫它进入某种线性组合是不好的。
顺便说一句,我建议您在立即调用该函数时避免 compose
:
checkAuthorization().then(() =>
searchItem(buildParams(someRequestData))
, e =>
handleError(e)
);
或者也许
checkAuthorization().then( compose(searchItem, buildParams, ()=>someRequestData)
, handleError ); // ^^^^ "const"
这是一个用于处理同步功能和 Promises 的组合器。看起来它可以正常维护订单:
// 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
我刚刚制作了一个 npm module 来处理优雅的 Promise
构图。
它仍处于早期阶段,但欢迎您检查代码并根据您的需要和标准对其进行更改。
基本上它提供了两种可能满足您需求的方法:
合并
使用 Promise.combine({...})
,您可以通过为对象提供一系列返回 Promises 的函数并接受先前函数的结果作为输入来组合多个 Promises,如下所示:
Promise.combine({
item: () => searchItem,
auth: ({item}) => checkAuth,
params: ({item, auth}) => buildParams
}).then(({item, auth, params}) => {
// here you can do what you need
})
减少
使用 Promise.reduce([...])
,您可以将 Promise 链接到一个返回 Promise 的函数数组中,并接受先前执行的 Promise 的输出作为输入:
Promise.reduce([
() => searchItem,
(item) => checkAuth,
(auth) => buildParams
]).then((params) => {
// here you can do what you need
})
请注意,在这种情况下,您将无法访问 .then()
函数中的 item
,但您始终可以编写 checkAuth
Promise 的结果,以便通过item
下游也是:
Promise.reduce([
() => searchItem,
(item) => checkAuth.then((auth) => {
return {auth, item}
}),
({auth, item}) => buildParams.then((params) => {
return {params, item}
}),
]).then(({params, item}) => {
// here you can do what you need
})
输入
您还可以像这样从请求中添加一些输入数据:
Promise.reduce([
(requestData) => searchItem,
(item) => checkAuth,
(auth) => buildParams
], requestData).then((params) => {
// here you can do what you need
})
看到我将 requestData
作为 Promise.reduce([...], requestData)
的第二个参数传递,它作为参数传递给第一个函数。
Here you can see the functions code. 希望这会有所帮助。