首页 > 解决方案 > Angular:将值从承诺分配给外部变量的问题

问题描述

我正在尝试将多张图片上传到 firebase 存储(从存储 base64 字符串的数组),获取 downloadURL 并将值分配到另一个数组中(在上传到云 firestore 之前)。

  testuploadpic() {
    this.skillImage = this.photoService.photos; //ignore this
    for (let i = 0; i<this.skillImage.length; i++) {
      try {
        const id = Math.random().toString(36).substring(2);
        const file = this.skillImage[i];
        const filePath = `user-skill-images/${this.session.uid}_skill_${id}`;
        const ref = firebase.storage().ref(filePath);
        ref.putString(file, 'base64', {contentType:'image/jpeg'}).then(function(snapshot) {
          console.log('Uploaded');
          ref.getDownloadURL().then(function(url) {
            console.log(url)   //I can get the url
            this.skillImageURL[i] = url;   //Problem is at here
            console.log(this.skillImageURL);   //I get undefined
          })
        })
      } catch(e) {
        this.toastSvc.showToast(e);
      }
    }
  }

我已经阅读了很多关于这个主题的内容,但仍然找不到解决我的问题的合适方法。感谢您抽出宝贵时间阅读我的问题并提供帮助。

标签: angulartypescriptfirebase

解决方案


这里我们有几个典型的新手问题:

  • 你失去了上下文
  • 使用嵌套异步函数时,您没有将循环变量存储到闭包中
  • 您正在尝试将异步 API 编写为同步的
  • 你违背了承诺链

试试这个(未测试):

function testuploadpic(){
    this.skillImage = this.photoService.photos; //ignore this
    //returns array of urls
    return Promise.all(this.skillImage.map(i=>{
        const id = Math.random().toString(36).substring(2);
        const file = this.skillImage[i];
        const filePath = `user-skill-images/${this.session.uid}_skill_${id}`;
        const ref = firebase.storage().ref(filePath);
        return ref.putString(file, 'base64', {contentType:'image/jpeg'}).then((snapshot)=> {
            console.log('Uploaded');
            return ref.getDownloadURL().then((url)=>{
                console.log(url)   //I can get the url
                return url;   //Problem is at here
            })
        }).catch(err=>{
            this.toastSvc.showToast(err);
        })
    }));
}

testuploadpic().then(urls=> console.log(`Urls: ${urls}`));

推荐阅读