PDFJS 和承诺减少
PDFJS and promise reducing
所以,看来我对js promises的理解还是很欠缺的。我正在使用 PDFJS 将 pdf 的所有页面显示为可滚动的画布列表(当前正在工作)。当我调整 window 大小时,我调用这样的函数(我有一个 pages
数组,它存储了 pdf.getPage(index)
:
中的所有 pdf 页面
// PART A
// This part works, though "pages" is a representation obviously
function reRender() {
const pages = [
pdfjsPage0, // the result of pdf.getPage(0)
pdfjsPage1,
pdfjsPage2,
];
return pages.reduce((accum, page, index) => accum.then(() => {
const viewport = page.getViewport(scale);
const canvas = canvases[index];
canvas.width = viewport.width;
canvas.height = viewport.height;
const ctx = canvas.getContext('2d');
const renderContext = {
canvasContext: ctx,
viewport,
};
return page.render(renderContext);
}), Promise.resolve());
}
但是,这段代码不会按预期工作,因为承诺似乎没有像我预期的那样返回:
// PART B
// This part only somewhat works, though "pages" is a representation obviously
// The promise will return and be resolved before all the pages have actually been rendered
// ie: reRender.then(//somecode), //somecode will execute before the pages have been rendered
function reRender() {
const pages = [
pdfjsPage0, // the result of pdf.getPage(0)
pdfjsPage1,
pdfjsPage2,
];
let promise = Promise.resolve(); //edited to add "()"
pages.forEach((page, index) => {
promise = promise.then(() => {
const viewport = page.getViewport(scale);
const canvas = canvases[index];
canvas.width = viewport.width;
canvas.height = viewport.height;
const ctx = canvas.getContext('2d');
const renderContext = {
canvasContext: ctx,
viewport,
};
return page.render(renderContext);
});
});
return promise;
}
然而,当抓取页面时,Promise 似乎需要以完全不同的方式构建,因为它有效(相同类型的构建不会等待或似乎按照我期望的顺序重新呈现:
// PART C
// This works, nothing in the caller.then will execute until everything
// has resolved here
function getPagesAndAddCanvas(pdf, pages = [], canvas = []) {
let promise = Promise.resolve();
for (let i = 1; i <= pdf.numPages; i++) {
promise = promise.then(() => pdf.getPage(i)
.then(page => {
pages.push(page);
const canvas = angular.element('<canvas></canvas>');
containerElement.append(canvas);
canvases.push(canvas[0]);
})
)
}
return promise;
}
然而,在我看来应该有效的东西,因为 PDFJS.getPage returns 一个承诺,这在某种程度上不起作用并且让我对我对承诺的理解感到非常困惑:
// PART D
// This does not work at all, pdf.getPage in this scenario
// does not seem to ever return
function getPagesAndAddCanvas(pdf, pages = [], canvas = []) {
const pageLength = Array(pdf.numPages).fill(1);
return pageLength.reduce((accum, irrelevant, index) => accum.then(() => {
console.log(pdf);
console.log(`index: ${index}`); // this is called for index 0
return pdf.getPage(index)
.then(page => {
console.log(page); // this is NEVER called
pages.push(page);
const canvas = angular.element('<canvas></canvas>');
containerElement.append(canvas);
canvases.push(canvas[0]);
return Promise.resolve(); //edited to fix spelling
});
}), Promise.resolve());
}
有谁知道 how/why 这些看似相互矛盾,因为 PART A 和 PART C 有效,但 PART B 和 PART D 无效?我在这里碰壁,失去了智慧。
B 部分不起作用,因为
let promise = Promise.resolve;
应该是
let promise = Promise.resolve();
(但只使用有效且更清洁的 A 部分)。
D 部分不起作用,因为
return Promise.resovle();
是一个拼写错误,因为与 C 部分相反,index
从 0
循环到 numPages-1
不同于从 1
运行的 i
至 numPages
.
您确实应该添加一些 .catch()
记录错误的处理程序,并查看控制台以查找未捕获的异常。
所以,看来我对js promises的理解还是很欠缺的。我正在使用 PDFJS 将 pdf 的所有页面显示为可滚动的画布列表(当前正在工作)。当我调整 window 大小时,我调用这样的函数(我有一个 pages
数组,它存储了 pdf.getPage(index)
:
// PART A
// This part works, though "pages" is a representation obviously
function reRender() {
const pages = [
pdfjsPage0, // the result of pdf.getPage(0)
pdfjsPage1,
pdfjsPage2,
];
return pages.reduce((accum, page, index) => accum.then(() => {
const viewport = page.getViewport(scale);
const canvas = canvases[index];
canvas.width = viewport.width;
canvas.height = viewport.height;
const ctx = canvas.getContext('2d');
const renderContext = {
canvasContext: ctx,
viewport,
};
return page.render(renderContext);
}), Promise.resolve());
}
但是,这段代码不会按预期工作,因为承诺似乎没有像我预期的那样返回:
// PART B
// This part only somewhat works, though "pages" is a representation obviously
// The promise will return and be resolved before all the pages have actually been rendered
// ie: reRender.then(//somecode), //somecode will execute before the pages have been rendered
function reRender() {
const pages = [
pdfjsPage0, // the result of pdf.getPage(0)
pdfjsPage1,
pdfjsPage2,
];
let promise = Promise.resolve(); //edited to add "()"
pages.forEach((page, index) => {
promise = promise.then(() => {
const viewport = page.getViewport(scale);
const canvas = canvases[index];
canvas.width = viewport.width;
canvas.height = viewport.height;
const ctx = canvas.getContext('2d');
const renderContext = {
canvasContext: ctx,
viewport,
};
return page.render(renderContext);
});
});
return promise;
}
然而,当抓取页面时,Promise 似乎需要以完全不同的方式构建,因为它有效(相同类型的构建不会等待或似乎按照我期望的顺序重新呈现:
// PART C
// This works, nothing in the caller.then will execute until everything
// has resolved here
function getPagesAndAddCanvas(pdf, pages = [], canvas = []) {
let promise = Promise.resolve();
for (let i = 1; i <= pdf.numPages; i++) {
promise = promise.then(() => pdf.getPage(i)
.then(page => {
pages.push(page);
const canvas = angular.element('<canvas></canvas>');
containerElement.append(canvas);
canvases.push(canvas[0]);
})
)
}
return promise;
}
然而,在我看来应该有效的东西,因为 PDFJS.getPage returns 一个承诺,这在某种程度上不起作用并且让我对我对承诺的理解感到非常困惑:
// PART D
// This does not work at all, pdf.getPage in this scenario
// does not seem to ever return
function getPagesAndAddCanvas(pdf, pages = [], canvas = []) {
const pageLength = Array(pdf.numPages).fill(1);
return pageLength.reduce((accum, irrelevant, index) => accum.then(() => {
console.log(pdf);
console.log(`index: ${index}`); // this is called for index 0
return pdf.getPage(index)
.then(page => {
console.log(page); // this is NEVER called
pages.push(page);
const canvas = angular.element('<canvas></canvas>');
containerElement.append(canvas);
canvases.push(canvas[0]);
return Promise.resolve(); //edited to fix spelling
});
}), Promise.resolve());
}
有谁知道 how/why 这些看似相互矛盾,因为 PART A 和 PART C 有效,但 PART B 和 PART D 无效?我在这里碰壁,失去了智慧。
B 部分不起作用,因为
let promise = Promise.resolve;
应该是
let promise = Promise.resolve();
(但只使用有效且更清洁的 A 部分)。
D 部分不起作用,因为
return Promise.resovle();
是一个拼写错误,因为与 C 部分相反,index
从 0
循环到 numPages-1
不同于从 1
运行的 i
至 numPages
.
您确实应该添加一些 .catch()
记录错误的处理程序,并查看控制台以查找未捕获的异常。