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

标签 javascript upload dom-events

我已经检查了 Stack Overflow 中与我的问题相关的所有问题,但找不到解决问题的方法。

我想做的是;用户尝试上传图片,他们在客户端调整大小,然后上传。我用过 Pica library .一个文件一切正常。但是,当我将其更改为多个文件时,我得到了最后一张图片的副本。

发生了什么:循环 1 到 N 次 -> resizeImg N 次

理想的解决方案:循环 1 -> resizeImg(1) -> 循环 2 -> resizeImg(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]));
    }
}

最佳答案

问题是你没有为 resizeImg 的每次调用单独绑定(bind) img - 你没有 varconstlet 在第一次使用 img 之前。您正在隐式创建一个全局变量。所以,对于解释器来说,它看起来像

var img;
function resizeImg(source) {
  img = new Image;
  img.src = source;
  img.onload = function() {

img 正在不断重新分配。因此,在所有迭代之后,img 最终将最后一个使用 resizeImg 创建的 img - 对其他 Image 已丢失。

因此,始终显式声明变量以确保每次调用 resizeImg 时都有一个单独的 img 绑定(bind)。对所有其他变量也执行相同的操作,否则它们将是隐式全局的。

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]));
    }
}

关于javascript - 如何同步调用异步 JavaScript 函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50518002/

相关文章:

javascript - 在 Mobile Safari 上执行操作(经过一段时间后)

javascript - 有没有一种内置的方法可以在 JavaScript 中本地创建自定义事件?

javascript - Firefox 中的默认事件对象?

javascript - 如何为文本区域中的单词添加标题?

javascript - 如何从Jquery DatePicker可编辑传递ID值

javascript - 在单引号和双引号内写入数据

java - 使用 Primefaces fileUpload 组件,当用户单击 "Cancel"时是否会触发事件?

blackberry - 如何逐步将应用程序上传到应用程序世界?

javascript - 根据 Angular 中的多个值过滤 ng-repeat

python - Google AppEngine Python Web上传文件并读取内容