在 Ramda 中有条件地承诺
Conditional with promise in Ramda
如何使用 R.cond
和 promise?
像这样..
const fetchBin = (url) => fetch(`https://httpbin.org${url}`).then((response) => {
var contentType = response.headers.get("content-type");
if(contentType && contentType.includes("application/json")) {
return response.json();
}
throw new TypeError("Oops, we haven't got JSON!");
})
const testStatus = (status) => fetchBin(`/status/${status}`);
const isOk = R.propEq('statusCode', 200);
const testCond = R.cond([
[ R.pipeP(testStatus, isOk), (resp) => console.log('The resp is ', resp) ],
[ R.T, (code) => console.log('The resp is NOT ok', code) ]
])
testCond(404)
// R.pipeP(testStatus, isOk)(404)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.24.1/ramda.min.js"></script>
我认为这就是您所追求的,通过将其与 testStatus
组合,您应该能够获得 response
对象并进行条件分支。
const fetchBin = (url) => fetch(`https://httpbin.org${url}`).then((response) => {
var contentType = response.headers.get("content-type");
if(contentType && contentType.includes("application/json")) {
return response.json();
}
throw new TypeError("Oops, we haven't got JSON!");
})
const testStatus = (status) => fetchBin(`/status/${status}`);
const isOk = R.propEq('statusCode', 200);
const testCond = R.pipeP(testStatus, R.cond([
[isOk, resp => console.log('The resp is OK :' + resp.statusCode)],
[R.T, resp => console.log('The resp is NOT OK :' + resp.statusCode)]
]));
testCond(404)
// R.pipeP(testStatus, isOk)(404)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.24.1/ramda.min.js"></script>
全新视角
it's good to remind ourselves that we should be the ones bending our programming languages, not the other way around
我觉得你走错了路。 fetchBin
是我们真正要找的人中的稻草人。我们需要一个接受 URL 和 returns 解析后的 JSON 响应的函数;让我们称这个人为fetchJSON
从那里,我们使用 fetchJSON
实现 fetchBin
– 资源 returns 是 404
状态还是 200
状态并不重要使用错误的内容类型(参见下面的 XML 示例)——无论哪种方式,promise 都将被正确地路由到错误处理程序(下面的 console.error
;或者 .then(console.log).catch(console.error)
)——这里的重点,如果我不清楚,是 fetchBin
不应该关心诸如 HTTP 状态代码是什么或响应的 Content-Type header 之类的细节——让它要求解析 JSON,不用担心其余的
我分享这个的原因是为了帮助你避免陷入特定的思维方式。 R.cond
是一个漂亮的 糟糕的 形式,如果我们完全诚实的话 – 它迫使您调整程序分支的语义,方法是将它封闭在一个数组中并创建 thunk 以保留您的程序可能永远不会使用的条件分支; true 惰性仅在 strictly-evaluated JavaScript using if/else
或 ?:
中可用;没有他们你还在做不必要的工作
一旦我们摆脱了像 R.cond
这样死板的形式,事情就会很自然地融合在一起 – 哎呀,我们甚至不需要 R.pipe
,或者 R.pipeP
,或者R
完全...
const fetchJSON = url =>
fetch (url)
.then (responseOK)
.then (parseJSON)
const responseOK = (response) =>
{
if (response.status >= 200 && response.status < 300)
return response
else
throw Object.assign (Error (response.statusText), { response })
}
const parseJSON = response =>
response.json ()
const fetchBin = (url) =>
fetchJSON ('https://httpbin.org' + url)
fetchBin ('/anything?a=b') .then (console.log, console.error)
// all things good !
// => { args: {a: 'b'}, data: '' ... }
fetchBin ('/status/404') .then (console.log, console.error)
// non-200 status goes to error handler
// => { Error: NOT FOUND ..., response }
fetchBin ('/xml') .then (console.log, console.error)
// bad JSON goes to error handler
// => SyntaxError: Unexpected token < in JSON at position 0
好的,所以我们在那里不需要 R
,但是这个答案并不意味着暗示一般 rule-of-thumb。 Ramda 是一个很棒的工具,可以教你很多关于函数式编程的知识——只记得有时退后一步,评估你的程序是否可以用 你 想要的方式表达,而不是担心关于语言(或库,或函数;R.cond
)想要什么
如何使用 R.cond
和 promise?
像这样..
const fetchBin = (url) => fetch(`https://httpbin.org${url}`).then((response) => {
var contentType = response.headers.get("content-type");
if(contentType && contentType.includes("application/json")) {
return response.json();
}
throw new TypeError("Oops, we haven't got JSON!");
})
const testStatus = (status) => fetchBin(`/status/${status}`);
const isOk = R.propEq('statusCode', 200);
const testCond = R.cond([
[ R.pipeP(testStatus, isOk), (resp) => console.log('The resp is ', resp) ],
[ R.T, (code) => console.log('The resp is NOT ok', code) ]
])
testCond(404)
// R.pipeP(testStatus, isOk)(404)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.24.1/ramda.min.js"></script>
我认为这就是您所追求的,通过将其与 testStatus
组合,您应该能够获得 response
对象并进行条件分支。
const fetchBin = (url) => fetch(`https://httpbin.org${url}`).then((response) => {
var contentType = response.headers.get("content-type");
if(contentType && contentType.includes("application/json")) {
return response.json();
}
throw new TypeError("Oops, we haven't got JSON!");
})
const testStatus = (status) => fetchBin(`/status/${status}`);
const isOk = R.propEq('statusCode', 200);
const testCond = R.pipeP(testStatus, R.cond([
[isOk, resp => console.log('The resp is OK :' + resp.statusCode)],
[R.T, resp => console.log('The resp is NOT OK :' + resp.statusCode)]
]));
testCond(404)
// R.pipeP(testStatus, isOk)(404)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.24.1/ramda.min.js"></script>
全新视角
it's good to remind ourselves that we should be the ones bending our programming languages, not the other way around
我觉得你走错了路。 fetchBin
是我们真正要找的人中的稻草人。我们需要一个接受 URL 和 returns 解析后的 JSON 响应的函数;让我们称这个人为fetchJSON
从那里,我们使用 fetchJSON
实现 fetchBin
– 资源 returns 是 404
状态还是 200
状态并不重要使用错误的内容类型(参见下面的 XML 示例)——无论哪种方式,promise 都将被正确地路由到错误处理程序(下面的 console.error
;或者 .then(console.log).catch(console.error)
)——这里的重点,如果我不清楚,是 fetchBin
不应该关心诸如 HTTP 状态代码是什么或响应的 Content-Type header 之类的细节——让它要求解析 JSON,不用担心其余的
我分享这个的原因是为了帮助你避免陷入特定的思维方式。 R.cond
是一个漂亮的 糟糕的 形式,如果我们完全诚实的话 – 它迫使您调整程序分支的语义,方法是将它封闭在一个数组中并创建 thunk 以保留您的程序可能永远不会使用的条件分支; true 惰性仅在 strictly-evaluated JavaScript using if/else
或 ?:
中可用;没有他们你还在做不必要的工作
一旦我们摆脱了像 R.cond
这样死板的形式,事情就会很自然地融合在一起 – 哎呀,我们甚至不需要 R.pipe
,或者 R.pipeP
,或者R
完全...
const fetchJSON = url =>
fetch (url)
.then (responseOK)
.then (parseJSON)
const responseOK = (response) =>
{
if (response.status >= 200 && response.status < 300)
return response
else
throw Object.assign (Error (response.statusText), { response })
}
const parseJSON = response =>
response.json ()
const fetchBin = (url) =>
fetchJSON ('https://httpbin.org' + url)
fetchBin ('/anything?a=b') .then (console.log, console.error)
// all things good !
// => { args: {a: 'b'}, data: '' ... }
fetchBin ('/status/404') .then (console.log, console.error)
// non-200 status goes to error handler
// => { Error: NOT FOUND ..., response }
fetchBin ('/xml') .then (console.log, console.error)
// bad JSON goes to error handler
// => SyntaxError: Unexpected token < in JSON at position 0
好的,所以我们在那里不需要 R
,但是这个答案并不意味着暗示一般 rule-of-thumb。 Ramda 是一个很棒的工具,可以教你很多关于函数式编程的知识——只记得有时退后一步,评估你的程序是否可以用 你 想要的方式表达,而不是担心关于语言(或库,或函数;R.cond
)想要什么