Javascript代码执行混乱,可以解决吗?

时间:2018-11-25 21:12:37

标签: javascript html

我正在尝试使这部分代码正常工作,并且似乎运行不正常。我在控制台日志中注意到了这一点。

<script>
            var wrapper = document.getElementById("myHTMLWrapper");
            var myHTML = '';
            var databaseRef = firebase.database().ref('items/');
            databaseRef.once('value', function(snapshot)
            {
              snapshot.forEach(function(childSnapshot) 
              {
                var childKey = childSnapshot.key;
                var childData = childSnapshot.val();
                myHTML += '<div class="card">';
                myHTML += '<div class="card-body">';
                var urlimage = '';
                storageRef.child('images/'+ childData.id +'.jpg').getDownloadURL().then(function(url){
                    urlimage = url;
                    console.log(urlimage);
                });
                console.log('url outside of function is: '+urlimage);
                myHTML += '<img src="'+ urlimage +'" class="img-thumbnail" height="">';
                console.log('images/'+ childData.id +'.jpg');
                myHTML += '<h4>'+ childData.sku + ' - ' + childData.name +'</h4>';
                myHTML += '</div>';
                myHTML += '</div>';
              });
              wrapper.innerHTML = myHTML;
            });
          </script>

似乎代码正在运行console.log('函数外部的url是:'+ urlimage);在运行console.log(urlimage);之前

我对Javascript不太熟悉,希望我对此有所帮助。

谢谢!

3 个答案:

答案 0 :(得分:2)

storageRef.child('images/'+ childData.id +'.jpg').getDownloadURL().then(function(url){
                urlimage = url;
                console.log(urlimage);
            });

您提供的代码中的上述代码实际上使用了Promises。在处理异步数据(例如来自服务器的数据)时,通常使用promise。在处理那段代码时,正在执行其他代码行,从而导致您所观察到的。通常无法预测异步代码的行为。

要使用urlimage,您可以执行以下操作。

storageRef.child('images/'+ childData.id +'.jpg').getDownloadURL().then(function(url){
myHTML += '<img src="'+ url +'" class="img-thumbnail" height="">';
        });

答案 1 :(得分:1)

getDownloadURL().then(...)在我看来像一个异步函数。异步(简称异步)是指javascript发出外部请求(例如下载文件),然后在外部请求完成后执行回调函数(then的参数)。通常,您应该期望javascript异步回调在启动请求的整个函数调用堆栈之后执行。

大多数具有异步功能的编程语言都具有等待的功能,通常称为“阻塞”,但是Javascript是一个例外。

Javascript不允许阻塞的原因是Javascript引擎是单线程的,因此对某个操作的阻塞会阻塞整个系统。

因此,很长一段时间以来,无法阻止函数等待异步调用完成并像正常的同步调用一样接听。

这很不方便,Javascript最终引入了async函数和await关键字,它们可以满足您的需求。

async function buildHtml(snapshot) {
   // Note the novel for-loop syntax. The inner function in forEach would break async.
   for(childSnapshot of snapshot) {
      var childKey = childSnapshot.key;
      var childData = childSnapshot.val();
      myHTML += '<div class="card">';
      myHTML += '<div class="card-body">';
      var urlimage = await storageRef.child('images/'+ childData.id +'.jpg').getDownloadURL(); // global state may change here
      myHTML += '<img src="'+ urlimage +'" class="img-thumbnail" height="">';
      myHTML += '<h4>'+ childData.sku + ' - ' + childData.name +'</h4>';
      myHTML += '</div>';
      myHTML += '</div>';
   }
   wrapper.innerHTML = myHTML;
}

答案 2 :(得分:1)

您在这里有异步代码。看起来getDownloadURL()promise。我不知道该功能做什么(谷歌说它来自firebase),但是它来自外部库。而且执行可能需要一些时间。

即使花费几毫秒。它总是在事件循环结束时移动。