web-dev-qa-db-ja.com

画像の読み込みで非同期待機

Temp.js

export default class Temp {
    async addImageProcess(src){
        let img = new Image();
        img.src = src;
        return img.onload = await function(){
          return this.height;
        }
    }
}

anotherfile.js

import Temp from '../../classes/Temp'
let tmp = new Temp()

imageUrl ="https://www.google.co.in/images/branding/googlelogo/2x/googlelogo_color_120x44dp.png"
let image = tmp.addImageProcess(imageUrl);
console.log(image)

上記は私のコードです。画像のURLがあり、async awaitを使用して画像のプロパティを取得しようとしましたが、機能していません。見逃したものがわかりません。

14
Rahul

ここでの問題は awaitの定義 ...

await演算子は、Promiseを待つために使用されます

Image.prototype.onloadプロパティは約束ではなく、割り当てもしていません。ロード後にheightプロパティを返したい場合は、代わりにPromise...を作成します。

addImageProcess(src){
  return new Promise((resolve, reject) => {
    let img = new Image()
    img.onload = () => resolve(img.height)
    img.onerror = reject
    img.src = src
  })
}

次に、次を使用してその値にアクセスします

tmp.addImageProcess(imageUrl).then(height => {
  console.log(height)
})

または、async関数内の場合

async function logImageHeight(imageUrl) {
  console.log('height', await tmp.addImageProcess(imageUrl))
}
28
Phil

提案されたソリューションは完璧に機能しますが、すべての非同期関数のプロミスを書くことを避けたいので、この目的のために汎用ユーティリティ関数を書きました。

javaScriptで

function onload2promise(obj){
    return new Promise((resolve, reject) => {
        obj.onload = () => resolve(obj);
        obj.onerror = reject;
    });
}

typeScriptで(いくつかの一般的な型チェックを含む):

interface OnLoadAble {
   onload: any;
}
function onload2promise<T extends OnLoadAble>(obj: T): Promise<T> {
   return new Promise((resolve, reject) => {
   obj.onload = () => resolve(obj);
   obj.onerror = reject;
 });
}

質問の例では、次のことができます。

async function addImageProcess(src){
    let img = new Image();
    let imgpromise = onload2promise(img); // see comment of T S why you should do it this way.
    img.src = src;
    await imgpromise;
    return this.height;
}

もちろん、Philsの回答の最後のコードブロックで説明されているように、anotherfile.jsでの呼び出しも非同期で発生するはずです。

7
Pinna_be