有些資料會不斷變動,實務上會要求以 Polling 方式不斷呼叫 API 回傳資料。
Version
Vue 3.0.11
Fluture 14.0.0
Future
每秒鐘呼叫一次 API 取得資料。
api/getBooks_.js
import axios from 'axios'
import { attemptP } from 'fluture'
export default () => attemptP(() => axios.get('/books'))
使用 attemptP()
將 Promise 轉成 Future。
<template lang='pug'>
ul
li(v-for='x in books') {{ x.title }} / {{ x.price }}
</template>
<script setup>
import { ref, onUnmounted } from 'vue'
import { write } from 'vue3-fp'
import { pipe, map, prop, path } from 'ramda'
import { fork, mapRej } from 'fluture'
import getBooks from '/src/api/getBooks_'
let books = ref([])
let pollingId = 0
!(function f() {
let polling = () => pollingId = setTimeout(f, 1000)
pipe(
getBooks,
map(prop('data')),
map(write(books)),
mapRej(path(['response', 'data', 'error'])),
fork(polling)(polling),
)()
})()
onUnmounted(() => clearTimeout(pollingId))
</script>
16 行
!(function f() {
let polling = () => pollingId = setTimeout(f, 1000)
pipe(
getBooks,
map(prop('data')),
map(write(books)),
mapRej(path(['response', 'data', 'error'])),
fork(polling)(polling),
)()
})()
使用 Named IIFE 持續呼叫 API:
getBooks
:呼叫 API 回傳 Futuremap(prop('data'))
:在 Resolved Future 內取得data
map(write(books))
:在 Resolved Future 內寫入books
statemapRej(path(['response', 'data', 'error']))
:在 Rejected Future 內取得response.date.error
fork(polling)(polling)
:無論 Rejected Future 或 Resolved Future 都繼續呼叫 API
Conclusion
- 透過
mapRef()
可在pipe()
內處理 Rejected Future,不必再如otherwise()
需另外組合 function 處理