點燈坊

失くすものさえない今が強くなるチャンスよ

使用 Future 處理相依性 API

Sam Xiao's Avatar 2021-05-29

實務上常遇到須先呼叫第一個 API 取得 id 後,才能以該 id 呼叫第二個 API 取得資料,這種相依性的 API 該如何處理呢 ?

Version

Vue 3.0.11
Fluture 14.0.0

Future

api000

按下 Get Category 會先呼叫 getBook() 取得 categoryId,再將 categoryId 傳入 getCategory() 取得 category

<template lang='pug'>
div
  button(@click='onClick') Get Category
div {{ category }}
</template>

<script setup>
import { ref } from 'vue'
import { write } from 'vue3-fp'
import { pipe, thunkify, map, path, chain } from 'ramda'
import { error } from 'wink-fp'
import { fork, mapRej } from 'fluture'
import getBook from './api/getBook_'
import getCategory from './api/getCategory_'

let category = ref('')

let onClick = pipe(
  thunkify(getBook)(1),
  map(path(['data', 'id'])),
  chain(getCategory),
  map(path(['data', 'category'])),
  mapRej(path(['response', 'data', 'error'])),
  fork(error)(write(category))
)
</script>

18 行

let onClick = pipe(
  thunkify(getBook)(1),
  map(path(['data', 'id'])),
  chain(getCategory),
  map(path(['data', 'category'])),
  mapRej(path(['response', 'data', 'error'])),
  fork(error)(write(category))
)

使用 pipe() 組合 onClick()

  • thunkify(getBook)(1):將 getBook() 轉成 Thunk 再傳入資料
  • map(path(['data', 'id'])):在 Resolved Future 內取得 data.id
  • chain(getCategory)getCategory() 回傳 Future,因此要寫在 chain() 內攤平
  • map(path(['data', 'category'])):在 Resolved Future 內取得 data.category
  • mapRej(path(['response', 'data', 'error'])):在 Rejected Future 內取得 response.date.error
  • fork(error)(write(category)):從 Future 內取出資料並處理 Rejected Future

Conclusion

  • 若要在 Future 內使用回傳 Future 的 function,則不能寫在 map() 內,要改用 chain()

Reference

Ramda, chain()