2つの非同期メソッドから値を返すにはどうすればよいですか?

メロンNG

サードパーティのライブラリを使用せずにイメージコンプレッサーを作成しようとしています。

これが私のコードです(最終的に圧縮された画像のblobを返します):

 async function CompressImage(File, Quality, FileType) {
        var canvas = document.createElement('canvas');
        var ctx = canvas.getContext('2d');
        var img = new Image;
        img.onload = function () {
            canvas.width = img.width;
            canvas.height = img.height;
            ctx.drawImage(img, 0, 0, img.width, img.height);                        
                canvas.toBlob(function (blob) {                    
                    return blob;
                }, FileType, Quality);            
            }
        }
        img.src = URL.createObjectURL(File);
    }

常に未定義の値を返しますが、私のコードには何の問題もないようです。

多分それは非同期の問題であることがわかりました。非同期メソッドです。img.onloadcanvas.toBlob

promiseこれらのメソッドを1つずつ実行し、最終的に値を返すように順序付けする方法がわからない場合は、がこれに役立つと思います。

どうすればこれを解決できますか?ありがとうございました。

セバスチャンエスピノサ

Promise代わりに使用します。async最終的には同じですが、構文的には異なります。Promiseでは、パラメーターとして2つの関数(通常はresolveandと呼ばれます)を取得しますreject。これらの関数は、コールバック内で問題なく実行できますが、async関数内では問題が発生します。awaitコールバックを受け取る関数を探す方法はありません(あなたができる約束ではないためawait)。

TLDR; async関数は、コールバックを実行する関数を適切に実行しませんresolve()。コールバック関数上にある場合でも、どこでも実行できるようにPromiseを直接使用します。

例えば:

function CompressImage(File, Quality, FileType) {
  var canvas = document.createElement('canvas');
  var ctx = canvas.getContext('2d');
  var img = new Image;
  var prom = new Promise(function(resolve) {
    img.onload = function () {
      canvas.width = img.width;
      canvas.height = img.height;
      ctx.drawImage(img, 0, 0, img.width, img.height);                        
          canvas.toBlob(function (blob) {                    
              return resolve(blob);
          }, FileType, Quality);            
      }
    }
    img.src = URL.createObjectURL(File);
  });
  return prom;
}

これでうまくいくはずです。のコールバックで解決するpromiseをどのように作成しているかを見てcanvas.toBlobください。気付いた場合、関数はasyncPromiseを直接返すためではありませんが、コードでは非同期のように扱うことができます。関数。

もう少し更新された構文でそれを行う別の方法は次のとおりです。

const CompressImage = async (File, Quality, FileType) => {
  const canvas = document.createElement('canvas');
  const ctx = canvas.getContext('2d');
  const img = new Image;
  return await (new Promise(resolve => {
    img.onload = () => {
        canvas.width = img.width;
        canvas.height = img.height;
        ctx.drawImage(img, 0, 0, img.width, img.height);                        
            canvas.toBlob(resolve, FileType, Quality);            
        }
    }
    img.src = URL.createObjectURL(File);
  }));
};

そして、同じである必要があります。

私はこれをテストしていませんが、壊れている場合はかなり近いです。

更新:

さて、あなたが提供したjsfiddleで遊んだ後、私は興味深い発見があります:

$(function () {
    $("#FileUploader").change(function () {
        StartCompress(this.files[0]);
    });
    function StartCompress(input) {
        $("#beforesize").text(input.size);
        CompressFile(input, 0.8).then(blob => $("#afteresize").text(blob.size));
        
    }
    function CompressFile(file, quality) {
      var canvas = document.createElement('canvas');
      var ctx = canvas.getContext('2d');
      var img = new Image();
      var prom = new Promise(resolve => {
        img.onload = () => {
          canvas.width = img.width;
          canvas.height = img.height;
          ctx.drawImage(img, 0, 0);
          canvas.toBlob(blob => {
            resolve(blob)
          }, file.type, quality);
        }
        img.src = URL.createObjectURL(file);
      });
      return prom;  
    }
});

私のocdが安心できるようにコードを少し変更しましたが、問題はMIME(FileTypecanvasです。ファイルタイプを提供していないため、ファイルタイプを取得して変換するだけでpng、ロスレス形式です。 、したがって、jpg画像(損失を許容する)を選択し、基本的に同じサイズに合うように拡大縮小すると、サイズが大きくなります。

今すぐコードを試してみてください(私はfile.typeファイルのタイプを提供するために使用していますcanvas.toBlob)、それは地獄に行きpng、私が指摘した問題に関連していると思います。

それが役に立てば幸い。

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

componentDidMountで2つの非同期メソッドを呼び出すにはどうすればよいですか?

分類Dev

void以外の値を返すことができる非同期メソッドを作成するにはどうすればよいですか?

分類Dev

WndProcから非同期メソッドを呼び出すにはどうすればよいですか?

分類Dev

EFの非同期SaveChangesから非同期メソッドを安全に呼び出すにはどうすればよいですか?

分類Dev

非同期メソッドから非同期メソッドを呼び出すにはどうすればよいですか?

分類Dev

F#で非同期メソッドを待つにはどうすればよいですか?

分類Dev

このメソッドを非同期にするにはどうすればよいですか?

分類Dev

非同期メソッドをリストに入れて、それらを繰り返し呼び出すにはどうすればよいですか?

分類Dev

1つのメソッドからArrayListとFileArrayを返すにはどうすればよいですか?

分類Dev

非同期Task <T>メソッドを同期的に実行するにはどうすればよいですか?

分類Dev

2次元の値をmainメソッドに返すにはどうすればよいですか?

分類Dev

単体テストの場合、非同期メソッドからの戻りnullをモックするにはどうすればよいですか?

分類Dev

Laravel 5.4で同じメソッド/関数から1つのビューに2つの変数を返すにはどうすればよいですか?

分類Dev

Mainで非同期メソッドを呼び出すにはどうすればよいですか?

分類Dev

非同期メソッドをループで生成するにはどうすればよいですか?

分類Dev

トレイトで非同期メソッドを定義するにはどうすればよいですか?

分類Dev

非同期メソッドの結果が得られるまでプログラムを一時停止するにはどうすればよいですか?

分類Dev

非同期ループから値を即座に返すにはどうすればよいですか?

分類Dev

postMessage()呼び出しから非同期で値を返すにはどうすればよいですか?

分類Dev

ネイティブJavaScriptで成功するまで、非同期メソッドを繰り返し呼び出すにはどうすればよいですか?

分類Dev

非同期メソッドのジェネリック拡張メソッドを作成するにはどうすればよいですか?

分類Dev

オン/オフスイッチを使用して非同期メソッドを繰り返し呼び出すにはどうすればよいですか?

分類Dev

Task.Resultなしでawaitを介して非同期メソッドから正確に結果を取得するにはどうすればよいですか?

分類Dev

パラメータを持つ非同期保護メソッドをモックするにはどうすればよいですか?

分類Dev

モックされた非同期メソッドで検証可能な期待値を設定するにはどうすればよいですか?

分類Dev

onCompleteのような非同期メソッドから取得した値をどのように扱いますか?

分類Dev

C#の汎用メソッドからNULLを返すにはどうすればよいですか?

分類Dev

C#の汎用メソッドからNULLを返すにはどうすればよいですか?

分類Dev

C#の汎用メソッドからNULLを返すにはどうすればよいですか?

Related 関連記事

  1. 1

    componentDidMountで2つの非同期メソッドを呼び出すにはどうすればよいですか?

  2. 2

    void以外の値を返すことができる非同期メソッドを作成するにはどうすればよいですか?

  3. 3

    WndProcから非同期メソッドを呼び出すにはどうすればよいですか?

  4. 4

    EFの非同期SaveChangesから非同期メソッドを安全に呼び出すにはどうすればよいですか?

  5. 5

    非同期メソッドから非同期メソッドを呼び出すにはどうすればよいですか?

  6. 6

    F#で非同期メソッドを待つにはどうすればよいですか?

  7. 7

    このメソッドを非同期にするにはどうすればよいですか?

  8. 8

    非同期メソッドをリストに入れて、それらを繰り返し呼び出すにはどうすればよいですか?

  9. 9

    1つのメソッドからArrayListとFileArrayを返すにはどうすればよいですか?

  10. 10

    非同期Task <T>メソッドを同期的に実行するにはどうすればよいですか?

  11. 11

    2次元の値をmainメソッドに返すにはどうすればよいですか?

  12. 12

    単体テストの場合、非同期メソッドからの戻りnullをモックするにはどうすればよいですか?

  13. 13

    Laravel 5.4で同じメソッド/関数から1つのビューに2つの変数を返すにはどうすればよいですか?

  14. 14

    Mainで非同期メソッドを呼び出すにはどうすればよいですか?

  15. 15

    非同期メソッドをループで生成するにはどうすればよいですか?

  16. 16

    トレイトで非同期メソッドを定義するにはどうすればよいですか?

  17. 17

    非同期メソッドの結果が得られるまでプログラムを一時停止するにはどうすればよいですか?

  18. 18

    非同期ループから値を即座に返すにはどうすればよいですか?

  19. 19

    postMessage()呼び出しから非同期で値を返すにはどうすればよいですか?

  20. 20

    ネイティブJavaScriptで成功するまで、非同期メソッドを繰り返し呼び出すにはどうすればよいですか?

  21. 21

    非同期メソッドのジェネリック拡張メソッドを作成するにはどうすればよいですか?

  22. 22

    オン/オフスイッチを使用して非同期メソッドを繰り返し呼び出すにはどうすればよいですか?

  23. 23

    Task.Resultなしでawaitを介して非同期メソッドから正確に結果を取得するにはどうすればよいですか?

  24. 24

    パラメータを持つ非同期保護メソッドをモックするにはどうすればよいですか?

  25. 25

    モックされた非同期メソッドで検証可能な期待値を設定するにはどうすればよいですか?

  26. 26

    onCompleteのような非同期メソッドから取得した値をどのように扱いますか?

  27. 27

    C#の汎用メソッドからNULLを返すにはどうすればよいですか?

  28. 28

    C#の汎用メソッドからNULLを返すにはどうすればよいですか?

  29. 29

    C#の汎用メソッドからNULLを返すにはどうすればよいですか?

ホットタグ

アーカイブ