使用带有 ramda 的 fetch api

using the fetch api with ramda

我正在学习 Ramda 并尝试实现无点编程。为了做到这一点,我尝试在这里和那里重构,但卡在了这个上面。

我显然认为这不起作用,因为调用是异步的,但我找不到这段代码有什么问题。

// Why is this
const toJSONRamda = R.pipe(
  R.prop('json'), // getting the 'json' function
  R.call // and calling it
)

// different from this
const toJSON = response => response.json()

// Works
fetch('https://jsonplaceholder.typicode.com/todos/1')
  .then(toJSON)
  .then(console.log)
  
// Does not Work
fetch('https://jsonplaceholder.typicode.com/todos/1')
  .then(toJSONRamda)
  .then(console.log)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>

这不起作用的原因是响应对象的 json 方法不是纯函数。真是一种方法。当您使用 pipe(prop('json'), call) 时,您试图将该方法作为纯函数调用。在某些情况下会起作用。但是在这里,json方法实际上使用了this。 Ramda 的 call 不提供任何 this 对象。

有一个 Ramda 替代品:

const toJSONRamda = R.invoker(0, 'json')

fetch('https://jsonplaceholder.typicode.com/todos/1')
  .then(toJSONRamda)
  .then(console.log)
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.js"></script>

invoker 使用方法。这些应该有助于描述它是如何工作的:

R.invoker(0, 'method')(obj) = obj['method']()
R.invoker(1, 'method')(a, obj) = obj['method'](a)
R.invoker(2, 'method')(a, b, obj) = obj['method'](a, b)
//...

但是,有一点不容错过。无点编程只有在提高可读性时才有用。这对我来说已经完全可读了:

fetch('https://jsonplaceholder.typicode.com/todos/1')
  .then(resp => resp.json())
  .then(console.log)

如果这只是一个学习练习,那么请务必尝试将其变成无积分版本。但我会保留它作为生产代码。