web-dev-qa-db-fra.com

Comment faire exécuter la promesse de manière synchrone?

J'utilise dom-to-image.js pour convertir dom en image png. Comme dom-to-image.js utilise promesse, le code s'exécute de manière asynchrone. Je veux exécuter la fonction .then de manière synchrone.

J'ai le code suivant:

domtoimage.toPng(document.getElementById("main")).then(function(dataUrl) {
    console.log(dataUrl);
}).catch(function(error) {
    console.error('oops, something went wrong!', error);
});

console.log("this console should be executed after console.log(dataUrl)")

Je veux exécuter la fonction .then d'abord, avant d'exécuter console.log("this console should be executed after console.log(dataUrl)").

Veuillez me dire un moyen d'y parvenir.

7
Jeffrin John

Pour ceux qui trébuchent là-dessus maintenant:

Si vous n'êtes pas concerné par IE support, vous pouvez utiliser async et wait pour exécuter la promesse comme si elle était synchrone. La syntaxe await suspendra l'exécution de la fonction jusqu'à ce que la promesse soit résolue, vous permettant d'écrire le code comme s'il n'y avait pas de promesse. Pour intercepter une erreur, vous l'enveloppez dans un try/catch bloquer.

Le seul hic est que l'utilisation de la syntaxe await vous oblige à l'envelopper dans une fonction déclarée avec async.

async function toPng() {
  try {
    let dataUrl = await domtoimage.toPng(document.getElementById("main"));
    console.log(dataUrl);
  }
  catch (error ) {
    console.error('oops, something went wrong!', error);
  }

  console.log("this console should be executed after console.log(dataUrl)")
}
4
Steven Lambert

Il y a bien sûr des raisons légitimes pour forcer l'exécution synchrone d'une promesse en js. Le plus évident est quand require 'un fichier qui doit être initialisé en utilisant des trucs asynchrones, et l'optimisation n'est pas une préoccupation primordiale.

On dirait que le paquet synchronized-promise semble qu'il devrait faire l'affaire. Dans votre cas (avertissement - non testé ..):

const dti = () => docstoimage.toPng(document.getElementById("main"))
  .then(dataUrl => console.log('url: ', dataUrl))
  .catch(err => console.error('oops: ', err))

const sp = require('synchronized-promise')
const syncDti = sp(dti)
syncDti() // performs the 'synchronized version'

console.log("this console should be executed afterwards")
1
fresidue