Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

82
Visualizações
OpenLayers synchronous execution through promise/await in a Vue serverless app

I am trying to create a for loop that at each iteration updates the params of an OpenLayers map and once it is renderedcomplete it extracts the context of the mapcanvas and adds it to a GIF object. I need these to run synchronously as to always allow the map and layers to rendered and only then for the context to be added. My hacky solution at the moment is to use a fixed time setInterval, but as suggested in this question I should use async/await/Promises. My question is how would I go about wrapping my functions in a Promise and ensure they execute in a sequence while maintainning access to the context (this) of the vue app?

My for loop would look something like :

for(let i = 0 ; i < this.dateArraySurface10.length - 1 ; i++)
{
    waterfall([
        this.setTimeSurface10(),
        this.map.renderSync(),
        this.myCallback(),
    ],    
    function(err){
        console.log("Waterfall error : ",err);
    });
}

where the functions are :

setTimeSurface10: function () {
    if (this.currentTimeSurface10 === null) {
        this.currentTimeSurface10 = this.startTimeSurface10;
    } else if (this.currentTimeSurface10 >= this.endTimeSurface10) {
        this.currentTimeSurface10 = this.startTimeSurface10;
    } else {
        this.currentTimeSurface10 = new Date(
            this.currentTimeSurface10.setMinutes(this.currentTimeSurface10.getMinutes() + 60)
        );
    }
    this.surface10.getSource().updateParams({ TIME: this.currentTimeSurface10.toISOString().split(".")[0] + "Z" });
},
myCallback: function () {
    const mapCanvas = document.createElement('canvas');
    const divElement = document.querySelector(".map");
    mapCanvas.width = divElement.offsetWidth;//size[0];
    mapCanvas.height = divElement.offsetHeight;//size[1];
    const mapContext = mapCanvas.getContext('2d');
    Array.prototype.forEach.call(
        document.querySelectorAll('.ol-layer canvas'),
        function (canvas) {
            if (canvas.width > 0) {
                const opacity = canvas.parentNode.style.opacity;
                mapContext.globalAlpha = opacity === '' ? 1 : Number(opacity);
                const transform = canvas.style.transform;
                const matrix = transform
                                        .match(/^matrix\(([^\(]*)\)$/)[1] //eslint-disable-line
                                        .split(',')
                                        .map(Number);
                CanvasRenderingContext2D.prototype.setTransform.apply(mapContext,matrix);
                mapContext.drawImage(canvas, 0, 0);
            }
        }
    );
    this.gif.addFrame(mapCanvas, {copy:true, delay: 200});
}
about 4 years ago · Juan Pablo Isaza
1 Respostas
Responde à pergunta

0

Thanks to some help from Mr. Hocevar at OpenLayers (whom I suggest you support if you can on Github Sponsor) I got an answer for anyone interested.

async mapToCanvasList() {
    for(let i = 0 ; i < this.dateArraySurface10.length - 1 ; i++)
    {
        this.setTimeSurface10();
        await new Promise(resolve => this.map.once('rendercomplete', resolve));
        this.myCallback();
    }
    this.gif.on('finished', function(blob) {
        window.open(URL.createObjectURL(blob));
    });
    this.gif.render();
},
myCallback: function () {
    const mapCanvas = document.createElement('canvas');
    const divElement = document.querySelector(".map");
    mapCanvas.width = divElement.offsetWidth;//size[0];
    mapCanvas.height = divElement.offsetHeight;//size[1];
    const mapContext = mapCanvas.getContext('2d');
    Array.prototype.forEach.call(
        document.querySelectorAll('.ol-layer canvas'),
        function (canvas) {
            if (canvas.width > 0) {
                const opacity = canvas.parentNode.style.opacity;
                mapContext.globalAlpha = opacity === '' ? 1 : Number(opacity);
                const transform = canvas.style.transform;
                const matrix = transform
                                        .match(/^matrix\(([^\(]*)\)$/)[1] //eslint-disable-line
                                        .split(',')
                                        .map(Number);
                CanvasRenderingContext2D.prototype.setTransform.apply(mapContext,matrix);
                mapContext.drawImage(canvas, 0, 0);
            }
        }
    );
    this.gif.addFrame(mapCanvas, {copy:true, delay: 200});
},

As you can see rendering the entire method asynchronous and adding an await promise for the rendercomplete event ensures that the loop waits and executes myCallback which adds the rendered context as a frame to the GIF object.

about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda