我正在尝试使这部分代码正常工作,并且似乎运行不正常。我在控制台日志中注意到了这一点。
<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不太熟悉,希望我对此有所帮助。
谢谢!
答案 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),但是它来自外部库。而且执行可能需要一些时间。
即使花费几毫秒。它总是在事件循环结束时移动。