web-dev-qa-db-ja.com

約束を同期的に実行する方法は?

Domをpng画像に変換するためにdom-to-image.jsを使用します。 dom-to-image.jsはpromiseを使用するため、コードは非同期に実行されます。 .then関数を同期的に実行したい。

私は次のコードを持っています:

_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)")
_

console.log("this console should be executed after console.log(dataUrl)")を実行する前に、最初に.then関数を実行します。

これを達成する方法を教えてください。

7
Jeffrin John

今これにつまずいた人のために:

IEサポートに関心がない場合は、 asyncおよびawait を使用して、約束が同期的であるかのように実行できます。await構文Promiseが解決するまで関数の実行を一時停止し、Promiseが存在しないかのようにコードを記述できるようにします。エラーをキャッチするには、try/catchブロックでラップします。

唯一の問題は、await構文を使用するには、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

もちろん、jsでpromiseの同期実行を強制する正当な理由はareです。最も明らかなのは、非同期のものを使用して初期化する必要があるファイルをrequire 'ingする場合であり、最適化は最優先事項ではありません。

パッケージ synchronized-promise のように思えますが、これはトリックを行う必要があるようです。あなたの場合(警告-未テスト..):

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