Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/413.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何同步调用异步JavaScript函数?_Javascript_Upload_Dom Events - Fatal编程技术网

如何同步调用异步JavaScript函数?

如何同步调用异步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

我已经检查了与堆栈溢出问题相关的所有问题,但找不到解决方法

我想做的是;用户试图上传图像,它们在客户端被调整大小,然后被上传。我用过。对于一个文件,一切正常。但是,当我将其更改为多个文件时,会得到上一个图像的副本

发生了什么:循环1到N次->调整大小N次

理想解决方案:循环1->调整大小(1)->循环2->调整大小(2)

任何帮助都将不胜感激

我的代码如下:

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
,每次都用最后一个图像重写它。您正在全局初始化它吗?