then() 在 promise.all() 解析之前首先运行

then() runs first before promise.all() is resolved

我正在使用 async-await 技术来解决 promises 但问题是 then() 在解决 promise.all() 之前先被调用。

已更新

changed from Promise<void> to Promise<string>, the result is same then() is being called before Promise.all()

// after uploading the image returns path
private async imageUpload(): Promise<string> {
    try {
      let img = await this.file.upload(this.imageToUpload, 'fileInput_image')
      img.subscribe((path: string) => {
        this.bg_img_url.setValue(path)
        console.log(this.bg_img_url.value) // returns url
        return this.bg_img_url.value
      })
   }
}

// after uploading the icon returns path    
private async iconUpload(): Promise<string> {
  try {
      let icon = await this.file.upload(this.iconToUpload, 'fileInput_icon')
      icon.subscribe((path: string) => {
        this.item_icon.setValue(path)
        console.log(this.item_icon.value) // returns url
        return this.item_icon.value
      })
   } 
}

现在的问题是我无法在需要时获取值

Promise.all([this.iconUpload(), this.imageUpload()])
      .then((x) => {
        console.log(this.bg_img_url.value) // ''
        console.log(this.item_icon.value) // ''
})

如何在执行then()之前先解决promise.all()

感谢您花时间解决我的问题。真的很高兴得到不同的方法和建议。谢谢大家

Promises 不应与 async await 一起使用 - 您需要决定所需的方法。

选项 1 - 只需使用 promise 并删除 async / await 装饰器。

选项 2 - 从承诺中删除 thenawait 确保您的代码将 "wait" 解决承诺:

async someFunction() {
...
await Promise.all([this.iconUpload(), this.imageUpload()])
... You can use the resolved values from your promises here
console.log(this.bg_img_url.value) // ''
console.log(this.item_icon.value)
}

您在订阅方法中尝试 return 结果。函数不等待执行订阅方法。在这里我看到 2 个 Observable 结果并且更喜欢使用 forkJoinhere 示例。另一种方式,return 来自 Observable 变量的承诺。

例子

// from imageUpload
return img.toPromise();

// from iconUpload
return icon.toPromise();

Promise.all([this.iconUpload(), this.imageUpload()])
  .then((x) => {
      console.log(x);
});

最简单
实际上,因为订阅是同步的。即使这样也行得通

// after uploading the image returns path
private async imageUpload(): Promise <string> {
  try {
    let img = await this.file.upload(this.imageToUpload, 'fileInput_image')
    img.subscribe((path: string) => {
      this.bg_img_url.setValue(path)
      console.log(this.bg_img_url.value) // returns url
    })
    return this.bg_img_url.value
  }
}

// after uploading the icon returns path    
private async iconUpload(): Promise <string> {
  try {
    let icon = await this.file.upload(this.iconToUpload, 'fileInput_icon')
    icon.subscribe((path: string) => {
      this.item_icon.setValue(path)
      console.log(this.item_icon.value) // returns url
    })
    return this.item_icon.value
  }
}

其他选项
你应该 return 来自这两个函数的 Promise

// after uploading the image returns path
private async imageUpload(): Promise <string> {
  return new Promise(resolve => {
    try {
      let img = await this.file.upload(this.imageToUpload, 'fileInput_image')
      img.subscribe((path: string) => {
        this.bg_img_url.setValue(path)
        console.log(this.bg_img_url.value) // returns url
        resolve(this.bg_img_url.value)
      })
    }
  })
}

// after uploading the icon returns path    
private async iconUpload(): Promise <string> {
  return new Promise(resolve => {
    try {
      let icon = await this.file.upload(this.iconToUpload, 'fileInput_icon')
      icon.subscribe((path: string) => {
        this.item_icon.setValue(path)
        console.log(this.item_icon.value) // returns url
        resolve(this.item_icon.value)
      })
    }
  })
}

或者像这样的 rxjs 方式

// after uploading the image returns path
private async imageUpload(): Promise <string> {
  try {
    let img = await this.file.upload(this.imageToUpload, 'fileInput_image')
    img.pipe(
      switchMap((path: string) => {
        this.bg_img_url.setValue(path)
        console.log(this.bg_img_url.value) // returns url
        return this.bg_img_url.value
      })
    ).toPromise()
  }
}

// after uploading the icon returns path    
private async iconUpload(): Promise <string> {
  try {
    let icon = await this.file.upload(this.iconToUpload, 'fileInput_icon')
    icon.pipe(
      switchMap((path: string) => {
        this.item_icon.setValue(path)
        console.log(this.item_icon.value) // returns url
        return this.item_icon.value
      })
    ).toPromise()
  }
}