Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/409.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript代码执行不正常,我可以修复它吗?_Javascript_Html - Fatal编程技术网

Javascript代码执行不正常,我可以修复它吗?

Javascript代码执行不正常,我可以修复它吗?,javascript,html,Javascript,Html,我正试图让这段代码正常工作,但它似乎已经出了问题。我在控制台日志中注意到了这一点 var wrapper=document.getElementById(“myHTMLWrapper”); var myHTML=''; var-databaseRef=firebase.database().ref('items/'); databaseRef.once('value',函数(快照) { snapshot.forEach(函数(childSnapshot) { var childKey=chi

我正试图让这段代码正常工作,但它似乎已经出了问题。我在控制台日志中注意到了这一点


var wrapper=document.getElementById(“myHTMLWrapper”);
var myHTML='';
var-databaseRef=firebase.database().ref('items/');
databaseRef.once('value',函数(快照)
{
snapshot.forEach(函数(childSnapshot)
{
var childKey=childSnapshot.key;
var childData=childSnapshot.val();
myHTML+='';
myHTML+='';
var urlimage='';
storageRef.child('images/'+childData.id+'.jpg').getDownloadURL().then(函数(url){
urlimage=url;
console.log(urlimage);
});
log('函数外部的url为:'+urlimage);
myHTML+='';
log('images/'+childData.id+'.jpg');
myHTML+=''+childData.sku+'-'+childData.name+'';
myHTML+='';
myHTML+='';
});
wrapper.innerHTML=myHTML;
});
getDownloadURL()。然后(…)
在我看来就像一个异步函数。异步(Asynchronous,缩写为Asynchronous)意味着javascript发出一个外部请求(例如下载一个文件),然后在外部请求完成后执行一个回调函数(参数为
然后
)。通常,您应该期望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;
}
异步函数buildHtml(快照){ //注意新的for循环语法。forEach中的内部函数将断开async。 用于(快照的子快照){ var childKey=childSnapshot.key; var childData=childSnapshot.val(); myHTML+=''; myHTML+=''; var urlimage=await storageRef.child('images/'+childData.id+'.jpg')。getDownloadURL();//全局状态可能在此处更改 myHTML+=''; myHTML+=''+childData.sku+'-'+childData.name+''; myHTML+=''; myHTML+=''; } wrapper.innerHTML=myHTML; }
这里有异步代码。看起来
getDownloadURL()
是一个。我不知道这个函数做什么(谷歌说它来自firebase),但它来自外部库。执行起来可能需要一些时间

即使需要几毫秒。它总是在事件循环的末尾移动

storageRef.child('images/'+ childData.id +'.jpg').getDownloadURL().then(function(url){
                urlimage = url;
                console.log(urlimage);
            });
您提供的代码中的上述代码实际上使用了承诺。在处理异步数据(例如,来自服务器的数据)时,通常使用承诺。当这段代码正在处理时,其他代码行正在执行,从而导致您所观察到的结果。异步代码的行为通常无法预测

要使用
urlmimage
,可以执行以下操作

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

这是因为异步!使用另一个
.then()
该措辞总是不适合异步。感谢您的回答。这似乎是问题所在。在继续之前,我是否可以等待回调函数解析?谢谢您的回答。这似乎是问题所在。是否有任何方法可以在继续之前等待回调函数解析?@JW yes,
wait
。令人惊讶的是,它是新的。谢谢。我刚刚尝试了你的解决方案,但现在它似乎只是跳过了myHTML+='';直到最后。在继续之前,我有没有办法等待承诺得到解决?您也可以包括其他代码行。承诺函数中以
myHTML+=
开头的感谢。我已经这样做了,但它似乎将整个myHTML字符串连接延迟到wrapper.innerHTML存储空myHTML的位置。我能做些什么来延迟其余javascript代码的执行吗?非常感谢您的时间和专业知识。您可以使用setTimeout延迟执行,但这绝对不是正确的方法。我认为整个代码都需要重新构造,但我还不知道怎么做,尤其是我对firebase不太熟悉。