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不太熟悉。