2017-07-20 15 views
2

Firebase Storage Webで私の最初の措置をしており、Javascriptが私の専門ではないと告白しています。Firebase Storageから複数のイメージをダウンロード

私は人の名前のリストを持つWebページ(PHP)を持っています。私はその名前の横に彼らの肖像画を表示したいと思います。イメージはFirebase Storageフォルダに保存されます。私はすでにこのページhttps://firebase.google.com/docs/web/setupの指示に従ってFirebase APIを追加しました

<div id="people_list"> 
    <div class="list_row"> 
     <div class="photo"> 
      <img id="photo1" src="images/stdphoto.png" width="50" height="50"> 
     </div> 
     <div class="name"> 
      People Name 1 
     </div> 
    </div> 
    <div class="list_row"> 
     <div class="photo"> 
      <img id="photo2" src="images/stdphoto.png" width="50" height="50"> 
     </div> 
     <div class="name"> 
      People Name 2 
     </div> 
    </div> 
</div> 

とこのようにそれを初期化します:ここで

は(PHPで生成された)HTMLの簡単な例である

firebase.initializeApp(config); 
firebase.auth().signInAnonymously(); // Ignoring security for now 

そして1枚の写真をロードするコードはここにあります。それは完全に動作します!

var storage = firebase.storage(); 
var refPath = storage.ref('photos/johnnydepp.jpg'); 
refPath.getDownloadURL().then(function(url) { 
    document.getElementById('photo1').src = url; 
}).catch(function(error) { 
    console.log(error); 
}); 

しかし、今は、私は、ページ内のすべての画像をロードしようとしていますので、私は(PHPでロードされた)ファイル名とJavascriptの配列変数を作成したANのようでした:

var photos = ["johnnydepp", "jimcarrey", "emmawatson"]; 

var photoId = 0; 
var refPath = null; 
var storage = firebase.storage(); 
for (var i = 0; i <= photos.length - 1; i++) { 
    photoId = i + 1; 
    refPath = storage.ref('photos/' + photos[i] + '.jpg'); 
    refPath.getDownloadURL().then(function(url) { 
     document.getElementById('photo' + photoId).src = url; 
    }).catch(function(error) { 
     console.log(error); 
    }); 
} 

I理由は分かりませんが、リストの最後の写真だけが読み込まれています。 Javascriptコンソールにエラーはありません。

私が間違っていることをご存知ですか?ありがとう!

EDIT(私の解決策):

const promises = []; 

photos.forEach(val => { 
      const promise = firebase.storage() 
        .ref('photos/' + val + '.jpg') 
        .getDownloadURL() 
        .catch(err => { 
      console.log('error', err); 
           return ""; 
        }) 
        .then(fileUrl => { 
           return fileUrl; 
        }); 
   promises.push(promise); 
}); 

Promise.all(promises) 
   .catch(err => { 
     console.log('error', err); 
   }) 
   .then(urls => { 
     for (var i = 0; i <= urls.length - 1; i++) { 
      if (urls[i] != '') { 
       document.getElementById('photo' + (i + 1)).src = urls[i]; 
      } 
     } 
}); 

答えて

1

ここでの問題は、あなたがループ内で非同期機能を使用していることで、あなたはこのように自己ラッピング機能を使用する必要があります。

for (var i = 0; i <= photos.length - 1; i++) { 
    photoId = i + 1; 
    refPath = storage.ref('photos/' + photos[i] + '.jpg'); 
    (function(pid) { 
     refPath.getDownloadURL().then(function(url) { 
      document.getElementById('photo' + pid).src = url; 
     }).catch(function(error) { 
      console.log(error); 
     }); 
    })(photoId); 
} 

あなたが受け取るためにあなたのコードは動作しません。あなたがgetElemById(photoId)と呼ぶとき、遅れた後のfirebaseからの値はphotoIdの値が既に変更されています。あなたはここに同じ動作を確認することができます

for (var i = 0; i <= photos.length - 1; i++) { 
    photoId = i + 1; 
    setTimeout(function() { 
     console.log(photoId); 
    }, 1000) 
} 

セルフラッピング機能は、お使いのphotoId

+1

デビッドありがとう!あなたの説明はとても良く、私は何が間違っているのか理解していました。私はあなたの答えを受け入れるだけでなく、質問に私の解決策を残します。 – Guybrush

0

フェッチダウンロードURLは、非同期リクエスト(約束)であり、あなたが終了する前のものをさせることなく、次のループサイクルを実行するため、最後のものだけが実行されます完全に。

私は別のアプローチをとることをお勧めします。

var photos = ["johnnydepp", "jimcarrey", "emmawatson"]; 

var photoId = 0; 
var storage = firebase.storage(); 
var promises = []; 
for (var i = 0; i <= photos.length - 1; i++) { 
    photoId = i + 1; 
    promises.push(storage.ref('photos/' + photos[i] + '.jpg').getDownloadURL()); 
} 

photoId = 0; 
Promise.all(promises, data => { 
    for (var i = 0; i <= photos.length - 1; i++) { 
     photoId = i + 1; 
     document.getElementById('photo' + photoId).src = data[i]; 
    } 
}); 
+0

はあなたにアナンドに感謝していますが、確かこの作品です続けるclosureを作成しますか?私はループを削除して静的な値を使用しても、動作させることはできません... – Guybrush

+0

ああ、コンソールログにエラーメッセージはありません。 – Guybrush

関連する問題