Skip to content

Commit b8161f1

Browse files
committed
refactor: turn events into promises
turn any once occuring event on any element into a promise. This pattern is already in use but now abstracted into a function.
1 parent 8c775d8 commit b8161f1

File tree

4 files changed

+23
-22
lines changed

4 files changed

+23
-22
lines changed

src/components/QrcodeReader.vue

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import * as Scanner from '../misc/scanner.js'
2929
import Camera from '../misc/camera.js'
3030
import { imageDataFromFile, imageDataFromUrl } from '../misc/image-data.js'
31+
import { hasFired } from '../misc/promisify.js'
3132
import isBoolean from 'lodash/isBoolean'
3233
3334
export default {
@@ -160,7 +161,7 @@ export default {
160161
}
161162
},
162163
163-
paused (paused) {
164+
async paused (paused) {
164165
const video = this.$refs.video
165166
166167
if (paused) {
@@ -172,11 +173,9 @@ export default {
172173
173174
video.play()
174175
175-
video.addEventListener(
176-
'timeupdate',
177-
() => { this.readyAfterPause = true },
178-
{ once: true }
179-
)
176+
await hasFired(video, 'timeupdate')
177+
178+
this.readyAfterPause = true
180179
}
181180
},
182181

src/misc/camera.js

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { imageDataFromVideo } from './image-data.js'
2+
import { hasFired } from './promisify.js'
23

34
class Camera {
45

@@ -41,11 +42,7 @@ export default async function (constraints, videoEl) {
4142
}
4243

4344
const stream = await navigator.mediaDevices.getUserMedia(constraints)
44-
45-
const streamLoadedPromise = new Promise((resolve, reject) => {
46-
videoEl.addEventListener('loadeddata', resolve, { once: true })
47-
videoEl.addEventListener('error', reject, { once: true })
48-
})
45+
const streamLoaded = hasFired(videoEl, 'loadeddata', 'error')
4946

5047
if (videoEl.srcObject !== undefined) {
5148
videoEl.srcObject = stream
@@ -62,7 +59,7 @@ export default async function (constraints, videoEl) {
6259
videoEl.playsInline = true
6360
videoEl.play() // firefox does not emit `loadeddata` if video not playing
6461

65-
await streamLoadedPromise
62+
await streamLoaded
6663

6764
return new Camera(videoEl, stream)
6865
}

src/misc/image-data.js

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { DropImageFetchError, DropImageDecodeError } from './errors.js'
2+
import { hasFired } from './promisify.js'
23

34
const canvas = document.createElement('canvas')
45
const canvasCtx = canvas.getContext('2d')
@@ -31,29 +32,23 @@ export async function imageDataFromUrl (url) {
3132
}
3233

3334
const image = document.createElement('img')
34-
35-
const imageLoadedPromise = new Promise((resolve, reject) => {
36-
image.onload = resolve
37-
})
35+
const imageLoaded = hasFired(image, 'load')
3836

3937
image.src = url
4038

41-
await imageLoadedPromise
39+
await imageLoaded
4240

4341
return imageDataFromImage(image)
4442
}
4543

4644
export async function imageDataFromFile (file) {
4745
if (/image.*/.test(file.type)) {
4846
const reader = new FileReader()
49-
50-
const readerLoadedPromise = new Promise((resolve, reject) => {
51-
reader.onload = event => resolve(event.target.result)
52-
})
47+
const readerLoaded = hasFired(reader, 'load')
5348

5449
reader.readAsDataURL(file)
5550

56-
const dataURL = await readerLoadedPromise
51+
const dataURL = (await readerLoaded).target.result
5752

5853
return imageDataFromUrl(dataURL)
5954
} else {

src/misc/promisify.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
2+
export function hasFired (element, successEvent, errorEvent) {
3+
return new Promise((resolve, reject) => {
4+
element.addEventListener(successEvent, resolve, { once: true })
5+
6+
if (errorEvent !== undefined) {
7+
element.addEventListener(errorEvent, reject, { once: true })
8+
}
9+
})
10+
}

0 commit comments

Comments
 (0)