如何使用JavaScript验证真实PDF文件并解决异步结果获取问题
解决Promise异步结果无法同步赋值的问题
这是个非常典型的异步操作时序问题,我来帮你理清楚原因和解决办法:
为什么state会是undefined?
你遇到的核心问题是异步操作的执行顺序:readFile是一个异步函数,它的.then()回调只会在文件读取完成后才会触发;而你写的if (state == "OK")是同步代码,会在readFile还没完成读取、.then()还没触发的时候就先执行了——这时候state根本还没被赋值,自然是undefined。
方案1:把后续逻辑放到.then()回调内部
最简单的解决方式,就是把需要用到校验结果的后续逻辑,直接写在.then()或者.catch()的回调里,确保代码在拿到结果后再执行:
readFile(file).then( function(value) { // 这里已经拿到了校验结果,直接处理后续逻辑 if (value == "OK"){ // 你的后续业务代码,比如上传文件、显示成功提示等 console.log("验证通过,文件是真实PDF"); } }, function(error) { console.log("验证失败,文件不是真实PDF"); // 处理错误逻辑,比如提示用户重新选择文件 } );
方案2:用async/await让代码看起来像同步执行
如果你觉得回调嵌套不够直观,可以用ES6的async/await语法,把异步代码写成同步的风格,但注意必须在async标记的函数内部使用await:
// 定义一个async函数来处理文件校验和后续逻辑 async function processFile(file) { try { // await会等待readFile的Promise完成,拿到结果后再往下执行 const state = await readFile(file); if (state == "OK"){ // 后续逻辑 console.log("验证通过,文件是真实PDF"); } } catch (error) { // 捕获reject的错误 console.log("验证失败,文件不是真实PDF"); } } // 调用这个async函数 processFile(file);
额外小提示:更严谨的PDF校验逻辑
你提到后续会优化校验逻辑,这里建议你校验文件开头的%PDF-标识(标准PDF文件的开头一定是%PDF-开头,比如%PDF-1.7),比单纯判断是否包含"PDF"要准确得多,修改你的readFile函数:
function readFile(file){ return new Promise((resolve, reject) => { const fr = new FileReader(); fr.onload = () => { // 校验文件开头是否为%PDF- if (fr.result.startsWith("%PDF-")){ resolve("OK"); } else { reject("Error"); } }; fr.onerror = reject; fr.readAsBinaryString(file); }); }
内容的提问来源于stack exchange,提问作者user3714154
相关产品推荐
相关产品推荐

