JS Promise ждет вложенной асинхронной функции

У меня проблема с правильным синхронизацией двух асинхронных операций, поэтому внешняя функция ожидает завершения внутренней функции, прежде чем продолжить. Решение, которое я пытаюсь реализовать, основано на существующем решении, использующем ES2015, поэтому я не могу использовать ожидание и должен работать с обещаниями.

Решение разделено на несколько классов, которые для упрощения обзора я называю Main, Invoker и Inner. Таким образом, основной класс использует экземпляр Invoker для асинхронного выполнения команды из внутреннего класса и затем должен ждать ответа, который работает, но не ждет асинхронного Image.onload () из setSize () Внутренний класс.

class Inner extends Component{
    setSize(size){
        const newImage = { url: null, imageName: canvasImage.imageName};
        
        ... some stuff...
        const tempImage = new Image();
        tempImage.src = canvas.toDataURL();
        tempImage.onload = function(){
        
            ... some stuff...
            const tempCanvas = document.createElement("canvas");
            const tempCtx = tempCanvas.getContext("2d");
            tempCtx.drawImage(image, x, y, xa, ya);

            newImage.url = tempCanvas.toDataURL();
        }
        return Promise.resolve(newImage);
    }
}


class Main{
    resize(size){
        imageData = this.execute(commandName,'setSize', size);
        
        imageData.then(image => {
            ... do stuff with image data...
        });
    }
    execute(commandName, ...args) {
        return this._invoker.execute(commandName, ...args);
    }
}

class Invoker{
    execute(...args) {

        let [command] = args;
        if (isString(command)) {
          command = commandFactory.create(...args);
        }

        return this._invokeExecution(command).then((value) => {
          this.clearRedoStack();

          return value;
        });
    }
}

Я уже пытался переместить «return Promise.resolve (newImage) в функцию setSize внутри функции onload, но затем я получаю сообщение об ошибке в вызывающей стороне из-за отсутствия разрешения. Любые идеи?

Вам нужно использовать new Promise, а не Promise.resolve, чтобы создать обещание, которое выполняется из обратного вызова onload.

Bergi 30.03.2021 01:09
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
1
31
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вам нужно вернуть обещание и разрешить его в onload.

setSize () {
  return new Promise((resolve, reject) => {
    ...
    tempImage.onload = function () {
      ...
      resolve(newimage)
    }
  })
}

Спасибо! Ваш ответ и ответ от oieduardorabelo помогли!

Andreas 31.03.2021 02:28
Ответ принят как подходящий

поскольку функция setSize использует синтаксис на основе обратного вызова с onload, вам нужно подождать, пока браузер не вызовет функцию в процессе,

вы можете вернуть обещание от setSize и обработать onload для resolve и onerror для reject, что-то вроде:

setSize(size){
    return new Promise((res, rej) => {
      const newImage = { url: null, imageName: canvasImage.imageName};
      
      ... some stuff...
      const tempImage = new Image();
      tempImage.src = canvas.toDataURL();
      tempImage.onload = function(){
      
          ... some stuff...
          const tempCanvas = document.createElement("canvas");
          const tempCtx = tempCanvas.getContext("2d");
          tempCtx.drawImage(image, x, y, xa, ya);

          newImage.url = tempCanvas.toDataURL();
          res(newImage);
      }
      tempImage.onerror = function(error) {
        rej(error)
      }
    })
}

Большое спасибо! Это решило мою проблему!

Andreas 31.03.2021 02:27

Другие вопросы по теме