Как вызвать асинхронную функцию JavaScript синхронно? - PullRequest
0 голосов
/ 24 мая 2018

Я занимался этой проблемой в течение последних 2 дней, и моя голова вот-вот взорвется.

Я проверил все вопросы, связанные с моей проблемой в SO, и не смог найти способисправить это.

То, что я пытаюсь сделать, это;Пользователь пытается загрузить изображения, они изменяются в размере на стороне клиента, а затем они загружаются.Я использовал Библиотека Пика .Все отлично работает для одного файла.Однако, когда я изменил его на несколько файлов, я получаю дубликаты последнего изображения.

Что происходит: цикл от 1 до N раз -> resizeImg N раз

Идеальное решение: цикл 1 ->resizeImg (1) -> Loop 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]));
    }
}

Ответы [ 2 ]

0 голосов
/ 25 мая 2018

Вы можете попытаться определить рекурсивную функцию следующим образом:

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 будет выполняться только после разрешения последнего обещания.

0 голосов
/ 25 мая 2018

Проблема в том, что у вас нет отдельной привязки img для каждого вызова resizeImg - у вас нет var или const или let перед первым использованиемimg.Вы неявно создаете глобальную переменную.Таким образом, для переводчика это выглядит примерно так:

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

img постоянно получает переназначается .Таким образом, после всех итераций img будет в итоге только последним img, созданным с помощью resizeImg - ссылки на другие Image будут потеряны.

Таким образом, всегда объявляйте переменные явно, чтобы каждый вызов 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]));
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...