Javascript 从Firebase存储返回下载URL的函数

Javascript 从Firebase存储返回下载URL的函数,javascript,angularjs,firebase,firebase-storage,Javascript,Angularjs,Firebase,Firebase Storage,我写这个函数是为了在我的angular应用程序中使用它来计算ng重复列表中的ng src。我需要使调用同步,以便每次调用函数时值都正确。问题是: 为什么此代码返回一个值: var storage = firebase.storage(); var returnVal; //causes sync issues var getImageUrl = function (time) { storage.ref('images/' + time + '.jpg').getDownloadURL(

我写这个函数是为了在我的angular应用程序中使用它来计算ng重复列表中的ng src。我需要使调用同步,以便每次调用函数时值都正确。问题是:

为什么此代码返回一个值:

var storage = firebase.storage();
var returnVal; //causes sync issues
var getImageUrl = function (time) {
    storage.ref('images/' + time + '.jpg').getDownloadURL().then(function (url) {
        returnVal = url;
    });
    return returnVal;
};
但这不起作用:

var storage = firebase.storage();
var getImageUrl = function (time) {
    var returnVal; //so that this is specific to the function
    storage.ref('images/' + time + '.jpg').getDownloadURL().then(function (url) {
        returnVal = url; //I simply want to return the value of 'url'
    });
    return returnVal;
};
你知道如何让getImageUrl()函数从返回url吗

这是文档链接:

最后,我将把它转换成一个$scope函数,使用类似的方法:

<div ng-repeat="message in messages">
    <img ng-src="{{ getImageUrl(message.time) }}">
</div>

函数的任何变体都不会返回非
null
未定义的值。您正在执行一个异步调用,在继续执行下面的代码之前不会等待结果。例如:

var storage = firebase.storage();
// Execute (1)
var getImageUrl = function (time) {
    // Execute (2)
    var returnVal;
    // Execute (3)
    storage.ref('images/' + time + '.jpg').getDownloadURL().then(function (url) {
        // Execute (unknown)
        returnVal = url;
    });
    // Execute (4)
    return returnVal;
};
// Execute (unknown times)
您不知道异步调用何时返回数据,但它总是在
returnVal之后因此
returnVal
为空

我建议:

$scope.images = [];
$scope.messages = { // whatever };
for (m in $scope.messages) {
    storage.ref('images/' + time + '.jpg').getDownloadURL().then(function (url) {
        // Might need $scope.$apply(function() {} ) surrounding
        $scope.images.push(url);
    });
}
那么在你看来,

<div ng-repeat="image in images">
    <img ng-src="{{ image }}">
</div>  


加载所有这些的时间取决于
$scope.messages
的大小。如果有大量数据,我建议您更改数据结构,这样您就不必对数据库进行多次调用。

函数的任何变体都不会返回非
null
未定义的值。您正在执行一个异步调用,在继续执行下面的代码之前不会等待结果。例如:

var storage = firebase.storage();
// Execute (1)
var getImageUrl = function (time) {
    // Execute (2)
    var returnVal;
    // Execute (3)
    storage.ref('images/' + time + '.jpg').getDownloadURL().then(function (url) {
        // Execute (unknown)
        returnVal = url;
    });
    // Execute (4)
    return returnVal;
};
// Execute (unknown times)
您不知道异步调用何时返回数据,但它总是在
returnVal之后因此
returnVal
为空

我建议:

$scope.images = [];
$scope.messages = { // whatever };
for (m in $scope.messages) {
    storage.ref('images/' + time + '.jpg').getDownloadURL().then(function (url) {
        // Might need $scope.$apply(function() {} ) surrounding
        $scope.images.push(url);
    });
}
那么在你看来,

<div ng-repeat="image in images">
    <img ng-src="{{ image }}">
</div>  


加载所有这些的时间取决于
$scope.messages
的大小。如果数据量很大,我建议您更改数据结构,这样您就不必多次调用数据库。

BlindProphet的回答包含了一个很好的解释,说明了当前代码不起作用的原因以及一个可行的解决方案

或者,您可以简单地返回
getDownloadURL()
返回的所谓承诺。我还没有测试过,但希望Angular自动接受承诺

var storage = firebase.storage();
var getImageUrl = function (time) {
    return storage.ref('images/' + time + '.jpg').getDownloadURL();
};
在HTML中,您只需保留:

<div ng-repeat="message in messages">
    <img ng-src="{{ getImageUrl(message.time) }}">
</div>

Blind Prophet的答案包含了一个很好的解释,说明了当前代码不起作用的原因以及一个有效的解决方案

或者,您可以简单地返回
getDownloadURL()
返回的所谓承诺。我还没有测试过,但希望Angular自动接受承诺

var storage = firebase.storage();
var getImageUrl = function (time) {
    return storage.ref('images/' + time + '.jpg').getDownloadURL();
};
在HTML中,您只需保留:

<div ng-repeat="message in messages">
    <img ng-src="{{ getImageUrl(message.time) }}">
</div>

您可以使用
ajax
firebase存储中下载文件

const link = linkYourFirebaseImage + folderStoreImage + '2F' + fileName;
// example: const link = https://firebasestorage.googleapis.com/v0/b/myApp.appspot.com/o/myDir%2F1608378322792.PNG;


function downloadImage(fileName, defaultImage) {
  if (fileName.length == 0) return defaultImage;

  let imageUrl;
  $.ajax({
    type: "GET",
    async: false,
    url: link ,
    success: function (response) {
      imageUrl = `${link}alt=media&token=${response.downloadTokens}`;
    },
  });

  return imageUrl;
}
如何使用?

const myImage = downloadImage('myPath.png', '../default.png');

您可以使用
ajax
firebase存储

const link = linkYourFirebaseImage + folderStoreImage + '2F' + fileName;
// example: const link = https://firebasestorage.googleapis.com/v0/b/myApp.appspot.com/o/myDir%2F1608378322792.PNG;


function downloadImage(fileName, defaultImage) {
  if (fileName.length == 0) return defaultImage;

  let imageUrl;
  $.ajax({
    type: "GET",
    async: false,
    url: link ,
    success: function (response) {
      imageUrl = `${link}alt=media&token=${response.downloadTokens}`;
    },
  });

  return imageUrl;
}
如何使用?

const myImage = downloadImage('myPath.png', '../default.png');
另见