首先自定義一個專門處理異步的 hooks
import {reactive, toRefs, ref } from "vue"; const useAsyncFn = (fn)=>{ let data = reactive({value:undefined ,loading:false,err:undefined}); let lastCallId = ref(0); const callBack = (...args)=>{ data.loading = true; const callId = ++lastCallId.value; // 避免短時間內,多次觸發。導致結果錯亂 fn(...args).then((res)=>{ if(callId === lastCallId.value){ data.value = res; data.loading = false; } },(err)=>{ if(callId === lastCallId.value){ data.err = err data.loading = false; } }) } return [toRefs(data),callBack]; } export default useAsyncFn
用法為:
let [data,callback] = useAsync(async(a)=>{ let project = await fetch("/xxx?a="+a).then(res=>res.json()); let iteration = await fetch("/xxx").then(res=>res.json()); return {project,iteration}}; }) onMounted(()=>{ callback(1) })
另外,如果想自動觸發調用,可以進異步封裝如下:
import useAsyncFn from "./useAsyncFn" const useAsync = (fn)=>{ const [ data,callback ] = useAsyncFn(fn); callback(); return data; } export default useAsync;
則用法為:
let res = useAsync(async()=>{ let project = await fetch("/xxx").then(res=>res.json()); let iteration = await fetch("/xxx").then(res=>res.json()); return {project,iteration}}; })