将提取API与Ramda结合使用

时间:2018-10-09 13:39:42

标签: javascript promise functional-programming fetch-api ramda.js

我正在学习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>

1 个答案:

答案 0 :(得分:8)

之所以不起作用,是因为响应对象的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)

如果这仅是学习活动,那么请务必尝试将其转换为无意义的版本。但是我会保留生产代码。