网站搜索

javascript - 如何等待一个可观察对象完成以返回一个值?


我有一个函数,如下。

 public getAssemblyTree(id: number) {
        ....
        const request = from(fetch(targetUrl.toString(), { headers: { 'responseType': 'json' }, method: 'GET' }));

        request.subscribe(
            (response) => {
                response.json().then(data => {
                    assemblyNodesForTree.push(...this.parseAssemblyTree(data['flat_assembly_graph']));
                }
                )
            }
        )
        console.log(assemblyNodesForTree)
        return assemblyNodesForTree;
    }

我意识到这个函数在 observable 完成之前就返回了 assemblyNodesForTree。我在想正确的方法可能是什么?

答案#1

你正在考虑将一个异步操作以同步方式运行。也涉及问题从RxJS Observable返回值。它解释了类似的用例。


快速建议:- 使用 fromFetch 替代 from(fetch)

为什么使用 fromFetch?- 因为它内部使用了 fetch API,并且在 API 调用完成后完成 observable。

你正在 getAssemblyTree 函数内部订阅,这个函数将在 ajax 完成后不久调用。在那之前,你只是返回,而你应该返回 assemblyNodesForTree 变量。那将永远是空的。

为了处理异步特性,你可以对你的 observable 进行管道处理,并在 map 操作符函数内部执行相关操作。最后从 getAssemblyTree 函数返回 Promise/Observable。

public getAssemblyTree(id: number) {
    ....
    const request = fromFetch({
      url: targetUrl.toString(), 
      headers: { 'responseType': 'json' }, method: 'GET' 
    }).pipe(
       map(async (response) => {
          const assemblyNodesForTree = [];
          const data = await response.json()
          assemblyNodesForTree.push(
            ...this.parseAssemblyTree(data['flat_assembly_graph'])
          );
          return assemblyNodesForTree;
       })
    );
    return request;
}

用法

async myFunction() {
  const assemblyNodesForTree = await lastValueFrom(getAssemblyTree(id))
}

这个函数的使用非常简单,使用 lastValueFrom() 调用 getAssemblyTree(id) 函数封装器。一旦 fromFetch API 调用完成,它将解析该 Promise。