then () запускается в первую очередь до разрешения обещания .all () - PullRequest
0 голосов
/ 13 июня 2018

Я использую async-await технику для решения promises, но проблема then() вызывается первой, прежде чем promise.all() разрешается.

Обновлено

изменено с Promise<void> на Promise<string>, результат тот же then() вызывается раньше 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) // ''
})

Как решить promise.all() сначала перед выполнением then()?

Спасибо за все, что вы потратили время на мою проблему.очень понравилось получать разные методы и предложения.Спасибо, ребята

Ответы [ 3 ]

0 голосов
/ 13 июня 2018

Вы пытаетесь вернуть результат в метод подписки.Функции не ждут выполнения метода подписки.Здесь я вижу 2 наблюдаемых результата и предпочитаю использовать forkJoin, здесь пример.Другой способ - вернуть обещания из наблюдаемых переменных.

пример

// from imageUpload
return img.toPromise();

// from iconUpload
return icon.toPromise();

Promise.all([this.iconUpload(), this.imageUpload()])
  .then((x) => {
      console.log(x);
});
0 голосов
/ 13 июня 2018

SIMPLEST
На самом деле, поскольку подписка является синхронной.Даже это будет работать

// 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 из обеих функций, как это

// 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()
  }
}
0 голосов
/ 13 июня 2018

Обещания не должны использоваться вместе с асинхронным ожиданием - вам нужно определиться с желаемым подходом.

Вариант 1 - Просто используйте обещание и удалите асинхронные / ожидающие декораторы.

Вариант 2 - Удалите then из обещания, await гарантирует, что ваш код будет "ждать" разрешения обещаний:

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)
}
...