點燈坊

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

Using Polling for Continuous API Call

Sam Xiao's Avatar 2021-11-13

If data is changing continuously, we will use polling for continuous API call to get data in practical.

Version

Vue 3.2

Composition API

polling000

Continuous API call every minute.

<script setup>
import { onUnmounted } from 'vue'
import axios from 'axios'

let articles = $ref ([])
let pollingId = 0

let url = 'http://localhost:8080/api/articles'

!(async function f() {
  let polling = _ => pollingId = setTimeout (f, 1000)
 
  try {
    let { data } = await axios.get (url)
    articles = data
  }
  catch (e) {
    console.error (e.response.statusText)
  }
  finally {
    polling ()
  }
}) ()

onUnmounted (_ => clearTimeout (pollingId))
</script>

<template>
  <ul>
    <li v-for="x in articles">{{ x.title }} / {{ x.content }}</li>
  </ul>
</template>

Line 10

!(async function f() {
  let polling = _ => pollingId = setTimeout (f, 1000)
 
  try {
    let { data } = await axios.get (url)
    articles = data
  }
  catch (e) {
    console.error (e.response.statusText)
  }
  finally {
    polling ()
  }
}) ()

Because we have to pass function to setTimeout for recursive, we have to use Named IIFE and only for function declaration, not arrow function.

Because of ASI, we have to add ! before IIFE.

Line 25

onUnmounted (_ => clearTimeout (pollingId))

Use clearTimeout to clear pollingId for polling in onUnmounted hook.

Point-free

polling000

Use Point-free style to get the same result.

<script setup>
import { ref, onUnmounted } from 'vue'
import { write } from 'vue3-fp'
import axios from 'axios'
import { pipe, map, prop, path, tap } from 'ramda'
import { encaseP, fork, mapRej } from 'fluture'
import { error } from 'wink-fp'

let articles = ref ([])
let pollingId = 0

let url = 'http://localhost:8080/api/articles'

!(async function f() {
  let polling = _ => pollingId = setTimeout (f, 1000)
  
  let showArticles = pipe ( 
    encaseP (axios),
    map (prop ('data')),
    mapRej (path (['response', 'statusText'])),
    fork (error) (write (articles)),
  )
  
  pipe (
    showArticles,
    polling
  ) (url)
}) ()

onUnmounted (_ => clearTimeout (pollingId))
</script>

<template>
  <ul>
    <li v-for="x in articles">{{ x.title }} / {{ x.content }}</li>
  </ul>
</template>

Line 17

let showArticles = pipe ( 
  encaseP (axios),
  map (prop ('data')),
  mapRej (path (['response', 'statusText'])),
  fork (error) (write (articles)),
)

We use Future in Point-free style.

Line 24

pipe (
  showArticles,
  polling
) (url)

Call polling in Function Pipeline.

Conclusion

  • We seldom use IIFE on ES6+, but it is a good way to use Named IIFE with setTimeout for recursive