我很难理解为什么我的代码不工作,我需要一些帮助
onMount(async() => {
// download the media file
if (post.file_name) {
await fetch(`/api/file?fileName=${post.file_name}`, {
method: 'GET'
})
// convert the file into displayable image, video, or audio
.then(async res => {
const blob = await res.blob()
if (blob.type.includes('image')) {
mediaType = 'image'
let reader = new FileReader()
reader.readAsDataURL(blob);
reader.onload = (event) => {
media = event.target?.result
}
}
else if (blob.type.includes('video')) {
mediaType = 'video'
media = URL.createObjectURL(blob)
}
else if (blob.type.includes('audio')) {
mediaType = 'audio'
// TODO implement this
}
})
.catch(err => {
console.error(err);
})
}
然后,我移动了该代码,并在.ts文件中添加了日志记录,并从相同的.svelte文件 调用它。。ts文件
export function getFileRepresentation(fileName: string) {
let file: FileRepresentation = {
string: '',
type: undefined
}
fetch(`/api/file?fileName=${fileName}`, {
method: 'GET'
})
// convert the file into displayable image, video, or audio
.then(async res => {
const blob = await res.blob()
if (blob.type.includes('image')) {
file.type = 'image'
let reader = new FileReader()
reader.readAsDataURL(blob);
reader.onload = (event) => {
file.string = event.target?.result
console.log('in promise');
console.log(file.string); // DEBUGGING
}
}
else if (blob.type.includes('video')) {
file.type = 'video'
file.string = URL.createObjectURL(blob)
}
else if (blob.type.includes('audio')) {
file.type = 'audio'
// TODO implement this
}
})
.catch(err => {
console.error(err);
})
console.log('on return');
console.log(file.string); // DEBUGGING
return file
}
。苗条的文件
onMount(async() => {
if (post.file_name) {
const file = await getFileRepresentation(post.file_name)
media = file.string
mediaType = file.type
}
.ts文件中的新代码不再工作。控制台。日志显示,首先调用的是'on return',带有file。字符串是一个空字符串,然后'in promise'一个被调用第二个字符串中有正确的值。为什么这里的代码与.svelte文件中的代码工作方式不同?这些都是客户端代码,所以我真的很困惑。
没有按预期工作的特定代码是第53-59行,但我注意到第6-63行可以工作,所以我不理解FileReader.load()是如何工作的
编辑:用代码片段替换截图
在Svelte文件中,您更新本地状态,执行顺序并不重要;在您尝试返回对象的提取代码中,情况并非如此。
顺序错误,您先返回对象并稍后设置其内容,当fetch
完成时异步设置。Svelte将不会收到这些更改的通知,因为代码位于组件之外。
如果您正在使用await
,那么我建议您也将它与fetch一致地使用。为了等待文件读取器的结果,可以将该部分转换为承诺。
try {
const res = await fetch(...);
const blob = await res.blob();
// ...
return file;
}
catch (error: any) {
// what used to be in `.catch(...)`
}
如果你要保留Promise链,你必须返回一个Promise,即异步代码开始的地方,最后一个then
应该返回最后的file
对象。
return fetch(...)
.then(res => {
// ...
return file;
})
(您可能还想检查获取结果的响应代码,有一个实用程序属性ok
检查它是否在200-299范围内。)