如何同步调用异步JavaScript函数?
我已经检查了与堆栈溢出问题相关的所有问题,但找不到解决方法 我想做的是;用户试图上传图像,它们在客户端被调整大小,然后被上传。我用过。对于一个文件,一切正常。但是,当我将其更改为多个文件时,会得到上一个图像的副本 发生了什么:循环1到N次->调整大小N次 理想解决方案:循环1->调整大小(1)->循环2->调整大小(2) 任何帮助都将不胜感激 我的代码如下:如何同步调用异步JavaScript函数?,javascript,upload,dom-events,Javascript,Upload,Dom Events,我已经检查了与堆栈溢出问题相关的所有问题,但找不到解决方法 我想做的是;用户试图上传图像,它们在客户端被调整大小,然后被上传。我用过。对于一个文件,一切正常。但是,当我将其更改为多个文件时,会得到上一个图像的副本 发生了什么:循环1到N次->调整大小N次 理想解决方案:循环1->调整大小(1)->循环2->调整大小(2) 任何帮助都将不胜感激 我的代码如下: function resizeImg(source) { img = new Image; img.src = sourc
function resizeImg(source) {
img = new Image;
img.src = source;
img.onload = function() {
width = img.naturalWidth;
height = img.naturalHeight;
ratio = Math.min(targetWidth / width, targetHeight / height);
resizer = window.pica();
canvas = document.createElement("canvas");
ctx = canvas.getContext("2d");
ctx.canvas.width = width * ratio;
ctx.canvas.height = height * ratio;
resizer.resize(img, canvas, {
quality: 3,
alpha: true,
unsharpAmount: 0
}).then(result => resizer.toBlob(result, 'image/jpeg', 0.90)).then(blob => imgBlobArray.push(blob)).then(function() {
console.log(i);
console.log(imgBlobArray);
});
};
}
document.getElementById('select').onchange = function(evt) {
for (i = 0; i < this.files.length; i++) {
resizeImg(window.URL.createObjectURL(this.files[i]));
}
}
function resizeImg(源代码){
img=新图像;
img.src=源;
img.onload=函数(){
宽度=img.自然宽度;
高度=img.自然高度;
比率=数学最小值(目标宽度/宽度,目标高度/高度);
resizer=window.pica();
canvas=document.createElement(“canvas”);
ctx=canvas.getContext(“2d”);
ctx.canvas.width=宽度*比率;
ctx.canvas.height=高度*比率;
调整大小(img、画布、{
质量:3,,
阿尔法:是的,
未锐化数量:0
}).then(result=>resizer.toBlob(result'image/jpeg',0.90)).then(blob=>imgBlobArray.push(blob)).then(function(){
控制台日志(i);
log(imgBlobArray);
});
};
}
document.getElementById('select').onchange=function(evt){
对于(i=0;i
问题在于,对于resizeImg
的每次调用,您没有单独绑定img
——在首次使用img
之前,您没有var
或const
或let
。您正在隐式创建一个全局变量。所以,对于口译员来说,它看起来像
var img;
function resizeImg(source) {
img = new Image;
img.src = source;
img.onload = function() {
img
不断被重新分配。因此,在所有迭代之后,img
最终将成为使用resizeImg
创建的最后一个img
——对其他图像的引用已丢失
因此,始终明确声明变量,以确保resizeImg
的每次调用都有一个单独的img
绑定。对所有其他变量也执行同样的操作,否则它们将是隐式全局变量
function resizeImg(source) {
const img = new Image;
img.src = source;
img.onload = function() {
const width = img.naturalWidth;
const height = img.naturalHeight;
const ratio = Math.min(targetWidth / width, targetHeight / height);
const resizer = window.pica();
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
ctx.canvas.width = width * ratio;
ctx.canvas.height = height * ratio;
resizer.resize(img, canvas, {
quality: 3,
alpha: true,
unsharpAmount: 0
}).then(result => resizer.toBlob(result, 'image/jpeg', 0.90)).then(blob => imgBlobArray.push(blob)).then(function() {
console.log(i);
console.log(imgBlobArray);
});
};
}
document.getElementById('select').onchange = function(evt) {
for (let i = 0; i < this.files.length; i++) {
resizeImg(window.URL.createObjectURL(this.files[i]));
}
}
function resizeImg(源代码){
const img=新图像;
img.src=源;
img.onload=函数(){
常数宽度=img.naturalWidth;
常数高度=img.自然高度;
常数比=数学最小值(目标宽度/宽度,目标高度/高度);
const resizer=window.pica();
const canvas=document.createElement(“canvas”);
const ctx=canvas.getContext(“2d”);
ctx.canvas.width=宽度*比率;
ctx.canvas.height=高度*比率;
调整大小(img、画布、{
质量:3,,
阿尔法:是的,
未锐化数量:0
}).then(result=>resizer.toBlob(result'image/jpeg',0.90)).then(blob=>imgBlobArray.push(blob)).then(function(){
控制台日志(i);
log(imgBlobArray);
});
};
}
document.getElementById('select').onchange=function(evt){
for(设i=0;i
您可以尝试这样定义一个递归函数
function resizeImgRec(files, i) {
if (i >= files.length)
return;
...
img.onload = function() {
...
resizer.resize(img, canvas, {
...
}).then(result => resizer.toBlob(result, 'image/jpeg', 0.90)).then(blob => imgBlobArray.push(blob)).then(function() {
console.log(i);
console.log(imgBlobArray);
resizeImg(files, i + 1);
});
};
}
document.getElementById('select').onchange = function(evt) {
resizeImgRec(this.files, 0);
}
这样,下一个resizeImg
只有在最后一个承诺得到解决后才会执行。我不知道这是不是因为你没有用var img
在顶部初始化img
,每次都用最后一个图像重写它。您正在全局初始化它吗?