异步函数重新进入而不被调用
async function re-entering without being called
这很可能是由于我对 JavaScript 的经验有限,但我一直无法弄清楚。这是一个Vue 2 + Typescript项目,但具体问题与Vue或Typescript无关
好的。所以我在我的一个组件中添加了以下功能。该组件的主要目的是获取 PDF 文件和 return 其第一页的光栅化版本 Blob
。这是我的功能:
async importButtonHandler () {
if (this.file) {
const blob = await this.pdfToBlob(this.file)
if (blob) {
const file2 = new File([blob], 'raster_pdf', { type: 'image/png' })
// Further processing
}
}
}
async pdfToBlob (pdfFile: File): Promise<Blob|null> {
const canvas: HTMLCanvasElement = document.createElement('canvas')
const buffer = await this.readFileAsync(pdfFile)
const typedarray = new Uint8Array(buffer)
// get handle of pdf document
const doc = await pdfjsLib.getDocument(typedarray).promise
// get handle of page
const pdfpage = await doc.getPage(1)
// get viewport to render the page at required scale
const viewport = pdfpage.getViewport()
// set canvas height same as viewport height
canvas.height = viewport.height
canvas.width = viewport.width
const renderContext: RenderParameters = {
canvasContext: canvas.getContext('2d') as CanvasRenderingContext2D,
viewport: viewport
}
// render the page contents in the canvas
await pdfpage.render(renderContext).promise
return new Promise((resolve, reject) => {
try {
canvas.toBlob(resolve)
} catch (error) {
reject(error)
}
})
}
readFileAsync (file: File): Promise<ArrayBuffer> {
return new Promise((resolve, reject) => {
const reader = new FileReader()
reader.onload = () => {
resolve(reader.result as ArrayBuffer)
}
reader.onerror = reject
reader.readAsArrayBuffer(file)
})
}
它命中函数 pdfToBlob
并从中调用 readFileAsync
,将文件正确读入 buffer
,但紧接着(在 const typedarray = new Uint8Array(buffer)
上)而不是执行那一行,它再次点击 pdfToBlob
函数然后抛出一个异常说:
TypeError: Cannot read properties of undefined (reading 'getDocument')
我一直想不明白为什么它又进入了这个函数(没有其他地方调用这个函数)。
我的直觉是,我在函数中 return 是关于 Promise,但我的所有实验都没有给我任何线索。
谁能帮我弄清楚这里出了什么问题?
想通了(有点)。
首先,我的 pdfjsLib
需要在调用 getDocument
之前正确导入并提供 worker。这是我第二个问题的原因。下面是在 Vue 2/Typescript 项目中导入 lib 和 worker 的正确方法:
import * as pdfjsLib from 'pdfjs-dist'
import pdfjsWorker from 'pdfjs-dist/build/pdf.worker.entry'
然后向图书馆提供工作人员并调用getDocument:
pdfjsLib.GlobalWorkerOptions.workerSrc = pdfjsWorker
const doc = await pdfjsLib.getDocument(YOUR_PDF_DATA).promise
我的 OP 中的其余代码工作正常。请注意,pdf.worker.entry
没有类型定义(或者至少我在任何地方都找不到它们),但它仍然有效。
第一个多次调用处理程序的问题似乎是 Vuetify 中的一个已知问题(或者行为,如果你愿意的话)。他们建议在定义 click
属性(如 @click.stop="importButtonHandler"
)时使用 native
、prevent
或 stop
来减轻这种行为。我试过没有成功。我的处理程序仍然被调用两次。在我的特定情况下,这不会造成任何功能性损害,所以我现在可以接受它,但我可以想到这种行为可能会造成灾难性后果的情况。
希望这对以后的人有所帮助。
这很可能是由于我对 JavaScript 的经验有限,但我一直无法弄清楚。这是一个Vue 2 + Typescript项目,但具体问题与Vue或Typescript无关
好的。所以我在我的一个组件中添加了以下功能。该组件的主要目的是获取 PDF 文件和 return 其第一页的光栅化版本 Blob
。这是我的功能:
async importButtonHandler () {
if (this.file) {
const blob = await this.pdfToBlob(this.file)
if (blob) {
const file2 = new File([blob], 'raster_pdf', { type: 'image/png' })
// Further processing
}
}
}
async pdfToBlob (pdfFile: File): Promise<Blob|null> {
const canvas: HTMLCanvasElement = document.createElement('canvas')
const buffer = await this.readFileAsync(pdfFile)
const typedarray = new Uint8Array(buffer)
// get handle of pdf document
const doc = await pdfjsLib.getDocument(typedarray).promise
// get handle of page
const pdfpage = await doc.getPage(1)
// get viewport to render the page at required scale
const viewport = pdfpage.getViewport()
// set canvas height same as viewport height
canvas.height = viewport.height
canvas.width = viewport.width
const renderContext: RenderParameters = {
canvasContext: canvas.getContext('2d') as CanvasRenderingContext2D,
viewport: viewport
}
// render the page contents in the canvas
await pdfpage.render(renderContext).promise
return new Promise((resolve, reject) => {
try {
canvas.toBlob(resolve)
} catch (error) {
reject(error)
}
})
}
readFileAsync (file: File): Promise<ArrayBuffer> {
return new Promise((resolve, reject) => {
const reader = new FileReader()
reader.onload = () => {
resolve(reader.result as ArrayBuffer)
}
reader.onerror = reject
reader.readAsArrayBuffer(file)
})
}
它命中函数 pdfToBlob
并从中调用 readFileAsync
,将文件正确读入 buffer
,但紧接着(在 const typedarray = new Uint8Array(buffer)
上)而不是执行那一行,它再次点击 pdfToBlob
函数然后抛出一个异常说:
TypeError: Cannot read properties of undefined (reading 'getDocument')
我一直想不明白为什么它又进入了这个函数(没有其他地方调用这个函数)。
我的直觉是,我在函数中 return 是关于 Promise,但我的所有实验都没有给我任何线索。
谁能帮我弄清楚这里出了什么问题?
想通了(有点)。
首先,我的 pdfjsLib
需要在调用 getDocument
之前正确导入并提供 worker。这是我第二个问题的原因。下面是在 Vue 2/Typescript 项目中导入 lib 和 worker 的正确方法:
import * as pdfjsLib from 'pdfjs-dist'
import pdfjsWorker from 'pdfjs-dist/build/pdf.worker.entry'
然后向图书馆提供工作人员并调用getDocument:
pdfjsLib.GlobalWorkerOptions.workerSrc = pdfjsWorker
const doc = await pdfjsLib.getDocument(YOUR_PDF_DATA).promise
我的 OP 中的其余代码工作正常。请注意,pdf.worker.entry
没有类型定义(或者至少我在任何地方都找不到它们),但它仍然有效。
第一个多次调用处理程序的问题似乎是 Vuetify 中的一个已知问题(或者行为,如果你愿意的话)。他们建议在定义 click
属性(如 @click.stop="importButtonHandler"
)时使用 native
、prevent
或 stop
来减轻这种行为。我试过没有成功。我的处理程序仍然被调用两次。在我的特定情况下,这不会造成任何功能性损害,所以我现在可以接受它,但我可以想到这种行为可能会造成灾难性后果的情况。
希望这对以后的人有所帮助。