若圖片 URL 不存在,會觸發 error
event,可藉由此技巧判斷圖片 URL 是否存在。
Version
Vue 3.0.11
Promise
若圖片 url 不存在,按下 Submit
會顯示 false
。
<template lang='pug'>
button(@click='onClick') Submit
div {{ result }}
</template>
<script setup>
import { ref } from 'vue'
import { write } from 'vue3-fp'
import { pipe, andThen as then, always as K } from 'ramda'
let result = ref ('')
let isImgUrlValid = url => new Promise (resolve => {
let img = new Image
img.onload = () => resolve (true)
img.onerror = () => resolve (false)
img.src = url
})
let onClick = pipe (
K ('https://picsum.photo/300/200/?random=10'),
isImgUrlValid,
then (write (result))
)
</script>
第 9 行
let isImgUrlValid = url => new Promise (resolve => {
let img = new Image
img.onload = () => resolve (true)
img.onerror = () => resolve (false)
img.src = url
})
當傳入 圖片 url 存在時,會觸發 load
event,否則會觸發 error
event,因此可藉由 onload
與 onerror
回傳 true
或 false
。
但問題來了,load
與 error
為 event,屬於 asynchronous 行為,因此無法直接以 synchronous 回傳 true
或 false
,因此只能回傳 Promise,由於我們只希望回傳 true
或 false
,因此只要回傳 Resolved 即可。
20 行
let onClick = pipe (
K ('https://picsum.photo/300/200/?random=10'),
isImgUrlValid,
then (write (result))
)
由於 isImgUrlValid
回傳 Promise,因此只能使用 then
從 Promise 取出 value 寫入 result
state。
Future
<template lang='pug'>
button(@click='onClick') Submit
div {{ result }}
</template>
<script setup>
import { ref } from 'vue'
import { write } from 'vue3-fp'
import S from 'sanctuary'
import { Future, value } from 'fluture'
let { unchecked: { pipe, K }} = S
let result = ref ('')
let isImgUrlValid = url => Future ((reject, resolve) => {
let img = new Image
img.onload = () => resolve (true)
img.onerror = () => resolve (false)
img.src = url
return () => {}
})
let onClick = pipe ([
K ('https://picsum.photo/300/200/?random=10'),
isImgUrlValid,
value (write (result))
])
</script>
16 行
let isImgUrlValid = url => Future ((reject, resolve) => {
let img = new Image
img.onload = () => resolve (true)
img.onerror = () => resolve (false)
img.src = url
return () => {}
})
一樣使用 load
與 error
event 回傳 true
或 false
,但改回傳 Future。
24 行
let onClick = pipe ([
K ('https://picsum.photo/300/200/?random=10'),
isImgUrlValid,
value (write (result))
])
由於 isImgUrlValid
回傳 Future,因此只能使用 value
從 Future 取出 value 寫入result
state。
Conclusion
- 若 function 想從 DOM event 回傳值,因為是 asynchronous 行為,因此只能回傳 Promise 或 Future