【问题标题】:Wait till the subscribe finishes then move on to next part of the code [duplicate]等到订阅完成然后继续下一部分代码[重复]
【发布时间】:2019-04-26 08:28:44
【问题描述】:

在设置完其他所有内容后调用订阅,但我想等到订阅完成。 T

尝试使用异步等待,但这对我不起作用。不知道是不是我做错了

public getGlobeConfig() {
    this.sourceKey = 'test';query = 'query'
    // wait till this call finishes than hit the 
     console.log('htting')
    this.service
    .searchQuery(query)
    .subscribe(response => {
        this.sources = response.hits.hits.map(hit => 
        hit._source);
        if (this.sources.length > 0) {
            this.availableMetadata = Object.keys(
                this.sources[0].metadata[this.sourceKey]
            );
        }
    });
    console.log('hitting')
    return this.sources
}

This.sources 到达未定义,因为 this.sources 正在订阅中设置

【问题讨论】:

  • 订阅是否返回回调或承诺,如果是,您可以尝试.subscribe(...).then(console.log('hitting'); return this.sources)
  • 看起来你已经陷入了异步编程的经典错误之一:)。异步回调在函数返回后被调用,而不是同时调用。虽然 javascript 看起来执行顺序是 start search query -> run callback -> return a value,但实际上是 start search query -> return a value; (稍后:)run callback。不必立即调用 Clalbacks。他们甚至可以在几天后被调用。并且您的其余代码不会等待回调完成(因此是异步的)。
  • 能否请您澄清您正在使用的库,并提供更多关于 searchQuery 来自何处的背景信息?

标签: javascript angular async-await


【解决方案1】:

简短的回答是您不能导致订阅后的代码等待。话虽如此,退一步查看您的代码,您不应该在getGlobeConfig 方法中订阅。您可能应该做的是在getGlobeConfig 方法中使用map 运算符并让getGlobeConfig 方法的使用者订阅:

public getGlobeConfig() {
  // ...
  return this.service.searchQuery(query).pipe(
    map(response => {
      // Transform the response to what you want
      // the consumer of this method to receive
    })
  );
}

消费者:

getGlobeConfig().subscribe(sources => /* ... */)

我从新的 RxJs 开发人员那里看到的一个非常常见的陷阱是,他们尝试订阅服务中的 Observables,然后想将数据返回给组件。在大多数情况下,您不会在服务中订阅。让服务对 RxJs 操作符中的数据进行操作,并让服务返回转换后的 Observables。最终消费者(通常是组件)将订阅服务返回的 Observables。

【讨论】:

    【解决方案2】:

    您的问题是您无法返回异步调用中生成的同步值。您能做的最好的事情就是返回一个承诺(或其他异步对象)。这就是 async await 旨在完成的任务:它添加了关键字,可以更轻松地等待 Promise 完成,但最终您仍在使用 Promise,并且异步函数总是返回 Promise。

    这里有一些简单的例子:

    function doSomethingWithPromise() {
      return somethingThatReturnsAPromise()
        .then((result) => result.calculateSomethingFromResult()) // `then` returns a promise with a result of the callback
    }
    

    转换为异步调用:

    async function doSomethingWithAsync() {
      // because this is an async function, it returns a promise here, before it finishes waiting
      let result = await somethingThatReturnsAPromise()
      return result.calculateSomethingFromResult() // at this point, after waiting, the function fulfills the promise with this return value
    }
    

    这两个例子是等价的。

    (这是一个通用示例,例如,如果您使用的是使用流或事件而不是 Promise 的库,情况可能会有所不同)

    【讨论】:

      猜你喜欢
      • 2015-10-04
      • 2012-06-08
      • 2011-04-26
      • 2012-01-29
      • 2021-11-12
      • 1970-01-01
      • 2018-12-05
      • 2015-07-11
      • 2021-12-26
      相关资源
      最近更新 更多