为何图片缩放函数的Promise无法resolve?技术求助
Hey there! Let's figure out why your resizeImage function's Promise is stuck in a pending state. The core issue here is almost certainly that your resolve (or reject) method never gets triggered—even though you expect it to fire on the image's onload event. Let's break down the most likely causes and fixes step by step:
1. Cached Images Skipping the onload Event
If the image you're processing is already cached by the browser, the onload event might fire before you've even attached the event listener. This means your resolve code never runs, leaving the Promise hanging.
Fix:
Check if the image is already loaded first, then either resolve immediately or attach the listener:
function resizeImage({ img, size }) { return new Promise((resolve, reject) => { const canvas = document.createElement('canvas'); pica.resize(img, canvas, { width: size.width, height: size.height }) .then(() => { const outputImg = new Image(); outputImg.src = canvas.toDataURL(); // Handle cached images first if (outputImg.complete) { resolve(outputImg); return; } // Attach listeners for non-cached images outputImg.onload = () => resolve(outputImg); outputImg.onerror = (error) => reject(new Error(`Output image failed to load: ${error.message}`)); }) .catch((error) => reject(new Error(`Pica resize failed: ${error.message}`))); }); }
2. Uncaught Errors in Pica's Resize Process
You mentioned suspecting Pica—if the resize method throws an error but you don't catch it, the Promise will never resolve or reject. Silent errors are a huge culprit here.
Fix:
Always add a .catch() to Pica's resize promise, and make sure you're passing valid parameters:
- Double-check that
imgis a fully loaded, valid<img>DOM element. - Ensure
size.widthandsize.heightare positive numbers (not 0, negative, orundefined). - Add console logs inside Pica's
.then()to confirm it's executing:pica.resize(img, canvas, { width: size.width, height: size.height }) .then(() => { console.log("Pica resize completed successfully!"); // Verify this logs // Rest of your code... }) .catch(reject);
3. Cross-Domain Image Blocking Canvas Operations
If your source image is from a different domain, the browser's same-origin policy might block canvas.toDataURL() from working. This will throw a security error that, if uncaught, leaves the Promise pending.
Fix:
- Set the cross-origin attribute on your source image before setting its
src:const img = new Image(); img.crossOrigin = "anonymous"; // Must come before src img.src = "https://example.com/your-image.jpg"; - Ensure the image server allows cross-origin requests (via CORS headers like
Access-Control-Allow-Origin).
4. Test Single Image Processing First
Before using Promise.all(), test a single resizeImage call to isolate the issue. This will tell you if the problem is in the function itself or how you're handling batch processing:
// Test a single resize first resizeImage({ img, size }) .then((resizedImg) => console.log("Resized image ready:", resizedImg)) .catch((err) => console.error("Resize failed:", err));
If this single call still hangs pending, focus on fixing the resizeImage function before scaling to batch processing.
Start with these checks—most of the time, the fix comes down to handling cached images, catching silent errors, or resolving cross-domain issues.
内容的提问来源于stack exchange,提问作者Le garcon

