【问题标题】:Typescript functions not in right order打字稿功能顺序不正确
【发布时间】:2019-01-21 15:02:25
【问题描述】:

我最近开始学习打字稿,到目前为止我很喜欢!目前正在尝试制作一个具有个人资料页面的网络应用程序,该应用程序具有更改个人资料图片的功能。

我有一个将图片上传到名为 store 的 firebase 函数,我还有一个名为 displayImage 的从 firebase 下载图片的函数。这两个函数都获取参数 photoType,该参数指示我们是更改封面照片还是个人资料照片。

它的工作方式是我知道它调用了 store 函数,并且在它打开文件选择器之前它提醒我它调用了 displayImage 函数。它是并行的,完成的第一个函数是 displayImage,它使用当前在 firebase 存储中的图像更新我当前的个人资料图像,然后将我选择的图像上传到 firebase。

我得到的最后一个警报是“上传成功”,这不是我想要的场景。

代码如下:

diplayActionSheet(){
const actionSheet = this.actionSheetCtrl.create({
  title: 'Select preferred action',
  buttons: [
    {
      text: 'Change profile picture',
      handler: () => {

        this.uploadAndDisplay("profile");
      }
    },{
      text: 'Change cover photo',
      handler: () => {
        this.uploadAndDisplay("cover");
      }
    },{
      text: 'Cancel',
      role: 'cancel',
      handler: () => {
        console.log('Cancel clicked');
      }
    }
  ]
});
actionSheet.present();
}

async uploadAndDisplay(photoType){
    await this.store(photoType);
    await this.displayImage(photoType);
}


store(photoType) {
    alert("Uslo u store sa parametrom photoType: " +photoType);
    this.fileChooser.open().then((url) => {
  (<any>window).FilePath.resolveNativePath(url, async (result) => {
    alert("Pre nego sto udje u uploadImage");
    this.nativepath = result;
    await this.uploadImage(photoType);
  }
  )
})
return Promise.resolve("test");
}

uploadImage(photoType) {
    alert("Uslo u uploadImage sa parametrom photoType: " +photoType);
    let imageName=this.angularFireAuth.auth.currentUser.uid+"__"+photoType;
    alert("imageName: " +imageName);
    (<any>window).resolveLocalFileSystemURL(this.nativepath, (res) => {
      res.file((resFile) => {
        var reader = new FileReader();
        reader.readAsArrayBuffer(resFile);
        reader.onloadend = (evt: any) => {
        var imgBlob = new Blob([evt.target.result], { type: 'image/jpeg' });
        imgBlob
      //
        var imageStore = this.firestore.ref().child("images/"+imageName); //firestore = firebase.storage();

        imageStore.put(imgBlob).then((res) => {

            alert('Upload Success');
          }).catch((err) => {
            alert('Upload Failed' + err);
          })
    }
  })
})
}
async displayImage(photoType){
    alert("pozvana funkcija: displayImage()");

    let imageName=this.angularFireAuth.auth.currentUser.uid+"__"+photoType;
    this.profileImgURL=this.angularFireAuth.auth.currentUser.uid+"__profile";
    alert("imageName==this.profileImgURL:" +imageName==this.profileImgURL);
    this.firestore.ref().child("images/"+this.profileImgURL).getDownloadURL().then((url) => {
      alert("displayImage");
      this.zone.run(()=>{
        alert("displayImage 2");
        var picElem = <HTMLImageElement>document.getElementById('myimg');
        alert("posle this.element = document.getElementById('myimg');");
        console.log("this.element: "+picElem);
        alert("this.element: "+picElem);
        picElem.src = url;
      })
})

我知道我可能使用了关键字 async 和 await 错误,但我真的不知道使用它们的正确方法。来自Java,这一切对我来说有点奇怪。 两个函数(store 和 displayImage)都可以很好地独立工作,如果我只是制作一个刷新按钮,我可以让它工作,但我真的不想要那样。

希望你们能帮助我,提前打气,非常感谢!

【问题讨论】:

    标签: angular typescript firebase asynchronous firebase-storage


    【解决方案1】:

    您将某些函数声明为async,但没有使用await 让它们在继续执行之前等待承诺返回。例如,在函数displayImage 中,您有这个块:

    this.firestore.ref().child("images/"+this.profileImgURL).getDownloadURL().then((url) =&gt; {...}

    这将创建由 getDownloadURL 返回的 promise,然后继续下一行,在本例中是函数的结尾,因此函数将在 promise 解析(完成)之前退出。在未来的某个时刻,promise 将解析,然后将执行 .then 回调,但此时函数已经退出。

    要等待它完成,您可以将其更改为:

    const url = await this.firestore.ref().child("images/"+this.profileImgURL).getDownloadURL();

    这将使函数等待getDownloadURL返回的promise的返回,然后才继续到函数的下一行,即结束。

    您的代码中还有其他地方也会发生这种情况,但我希望这个解释足以让您也可以应用相同的技术。

    【讨论】:

    • 感谢您的精彩解释!稍微调整了一下,得到了正确的组合:D 非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-28
    • 2022-01-24
    • 1970-01-01
    • 1970-01-01
    • 2020-04-25
    相关资源
    最近更新 更多