實務上常遇到 API 需要以 POST 以 Body 傳入,傳統會使用 Promise 處理,事實上 Future 更適合 Point-free。
Version
Vue 3.0.11
Fluture 14.0.0
Future
按下 Submit
後會將 ID
與 Password
以 POST 傳入資料。
api/login_.js
import axios from 'axios'
import { attemptP } from 'fluture'
export default body => attemptP (() => axios.post('/login', body))
attemptP
:將回傳 Promise 的 function 轉成 Future
App.vue
<template lang='pug'>
div
span ID
input(v-model='id')
div
span Password
input(v-model='password', type='password')
div
button(@click='onClick') Submit
div {{ result.id }}
div {{ result.password }}
</template>
<script setup>
import { ref, unref } from 'vue'
import { write } from 'vue3-fp'
import { pipe, map, prop, path, zipObj } from 'ramda'
import { error } from 'wink-fp'
import { fork, mapRej } from 'fluture'
import login from '/src/api/login_'
let id = ref ('')
let password = ref ('')
let result = ref ({})
let onClick = pipe (
() => [unref (id), unref (password)],
zipObj (['id', 'password']),
login,
map (prop ('data')),
mapRej (path (['response', 'data', 'error'])),
fork (error) (write (result))
)
</script>
26 行
let onClick = pipe (
() => [unref (id), unref (password)],
zipObj (['id', 'password']),
login,
map (prop ('data')),
mapRej (path (['response', 'data', 'error'])),
fork (error) (write (result))
)
使用 pipe
組合 onClick
:
() => [unref(id), unref(password)]
:使用unref()
讀取 state 並以 Array 回傳,這裡不能使用 K combinator,Vue 3 會失去 reactivityzipObj (['id', 'password'])
:組合出 Object 準備傳入login
login
:呼叫 API function 回傳 Futuremap (prop ('data'))
:在 Resolved Future 內取得data
mapRej (path (['response', 'data', 'error']))
:在 Rejected Future 內取得response.date.error
fork (error) (write(result))
:從 Future 內處理 Rejected Future,並從 Resolved Future 內取出資料寫入result
state
Conclusion
- 透過
mapRef
可在pipe
內處理 Rejected Future,不必再如otherwise
需另外組合 function 處理