【问题标题】:Unable to get data from service using the Observable in first click无法在第一次单击时使用 Observable 从服务中获取数据
【发布时间】:2022-01-04 12:35:06
【问题描述】:

我正在开发一个函数以从我创建的服务中获取字符串值。

googlemap.service.ts

app.component.ts

我正在尝试获取持续时间,但结果是这样的,我需要单击两次才能获得预期的结果。

结果

如何一键获取结果。

更新

【问题讨论】:

  • 你以后如何处理 travelDuration?在模板或其他方法中使用它?

标签: angular typescript rxjs observable


【解决方案1】:

代码存在多个问题:

  • setTravelDuration 返回的 observable 是同步的,而不是异步的。甚至在 directionService.route 执行回调之前,您已经返回了一个可在订阅时立即执行的 observable。
  • console.log('duration on map ...') 将同步执行,不考虑 subscribe 中编写的代码。

对于第二点,您可以简单地将console.log 移动到订阅中,即在console.log('x', x) 之后。

对于第一点,您可以编写如下代码:

    // within setTravelDuration method
    const directionServicePromise = new Promise<string>((resolve, reject) => {
      directionService.route({
        origin: origin,
        // Remaining options
      }, (res, status) => {
        if (status === 'OK') {
          // Perform some logic
          // ...
          const text = data?.duration!.text || '';
          resolve(text) // provide the value as per your use case
        } else {
          // resolve or reject as per your use case
        }
      });
    });
    
    return from(directionServicePromise);

【讨论】:

  • 但出现错误“string | undefined” not assignable to string | PromiseLike,我更新了问题@Siddhant 的错误
  • @kiku 我没有测试代码,因为它没有共享。我已经编辑了答案,看看是否有帮助。 PS:我只是试图举例说明如何实现它。您必须确保将字符串传递给resolve 或相应地处理其他地方的类型。如果您仍然遇到问题,请通过 stackblitz 分享代码。
  • 谢谢,它确实有效!
【解决方案2】:

第二次不起作用,因为您必须单击两次,它起作用是因为当您第二次单击时,您同时收到了第一个请求的响应,并且 this.travelDuration 现在已初始化。

真正的问题是 console.log 在订阅回调之外。 您正在尝试从异步代码中获取同步数据。

通过订阅异步可观察对象,这意味着当您从请求中获得响应时将调用回调。

如您所见,console.log(x, x)在两次单击之间显示在您的控制台中:

  • 第一次点击
  • 请求已发送
  • 第二个 console.log 被调用(未定义)
  • 收到响应
  • 内部console.log被调用(初始化)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-04-12
    • 1970-01-01
    • 1970-01-01
    • 2014-01-21
    • 2020-10-10
    • 2021-11-23
    • 2017-06-12
    相关资源
    最近更新 更多