Promise.all返回结果异常:页面Promise未正确解析问题求助
PDF.js处理PDF时Promise.all返回异常的原因与修复
问题描述
我用PDF.js编写了一段处理PDF的代码,但无法正确返回所有Promise的结果。第一个Promise元素返回正常,但第二个元素带有“Promise {:”标识,不清楚这代表什么。
原代码如下:
pdfjs.getDocument(file).promise.then((docData) => { const pageCount = docData._pdfInfo.numPages; const outlinePromises = docData.getOutline().then((outline) => { return outline }) const pagePromises = Array.from( { length: pageCount }, (_, pageNumber) => { return docData.getPage(pageNumber + 1).then((pageData) => { return pageData.getTextContent().then((textContent) => { //console.log(pageData) return textContent.items.map(({ str }) => str).join(" "); }); }); } ) return Promise.all([outlinePromises, pagePromises]).then((response) => { setOutline(response[0]) setPages(response[1]); console.log(response) }); });
问题原因
核心问题是你错误地把Promise数组作为单个元素传给了Promise.all。Promise.all的作用是接收一个Promise数组,等待数组里的每个Promise都完成后返回结果数组。但你现在传的是[outlinePromises, pagePromises]——其中outlinePromises是单个Promise,而pagePromises本身就是一个Promise数组。Promise.all会把pagePromises这个数组当作普通非Promise元素直接返回,不会解析它内部的每个Promise,所以你看到的第二个元素还是一堆未完成的Promise对象。
修复方案
只需要把pagePromises里的所有Promise展开到Promise.all的参数数组中,让Promise.all直接处理所有单个Promise即可。同时可以简化outlinePromises的写法,因为getOutline()本身就是Promise,不需要额外的.then包装。
修复后的代码:
pdfjs.getDocument(file).promise.then((docData) => { const pageCount = docData._pdfInfo.numPages; // 直接使用getOutline返回的Promise,无需额外then const outlinePromise = docData.getOutline(); const pagePromises = Array.from( { length: pageCount }, (_, pageNumber) => { return docData.getPage(pageNumber + 1).then((pageData) => { return pageData.getTextContent().then((textContent) => { return textContent.items.map(({ str }) => str).join(" "); }); }); } ) // 使用扩展运算符把pagePromises的所有Promise展开到数组中 return Promise.all([outlinePromise, ...pagePromises]).then((response) => { // 第一个元素是大纲数据,后面的所有元素对应每页的文本 setOutline(response[0]); setPages(response.slice(1)); console.log(response); }); });
如果你更习惯分开处理,也可以先合并所有Promise再调用Promise.all:
// 另一种写法:合并大纲Promise和页面Promise数组 const allPromises = [outlinePromise, ...pagePromises]; Promise.all(allPromises).then((response) => { setOutline(response[0]); setPages(response.slice(1)); });
内容的提问来源于stack exchange,提问作者Ricardo Capozza
相关产品推荐
相关产品推荐

