如何将Observable设置为void?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何将Observable设置为void?相关的知识,希望对你有一定的参考价值。

我正在使用Observable从Http端点获取数据。如果我没有在此行A function whose declared type is neither 'void' nor 'any' must return a value.中添加return语句,则会收到此错误return https.get(urls[i], res =>。在此处添加return语句时,urls数组无法访问第二个端点。有什么办法可以解决?

const https = require('https');
@Injectable()
export class MessageService {
  constructor() {}

  message = new ProductMessage();
  publishMessages(productEvent: ProductEvent): Observable<any> {
    let json = '';
const url = this.configService.get('SITEMAP_ENDPOINT');
    const urls = [
      'https://' + url + '/blc,
      'https://' + url + '/eye
    ];
    try {
      for (let i = 0; i < urls.length; i++) {
        return https.get(urls[i], res => {  ---------> How can I remove return? 
          res.on('data', function(chunk) {
            json += chunk;
          });
          res.on('end', function() {
            const result = JSON.parse(json);
            for (let i = 0; i < result.length; i++) {
              for (let j = 0; j < result[i].products.length; j++) {
                if (
                  //some condition
                ) {
                  for (let k = 0; k < productEvent.productCodes.length; k++) {
                    if (
                       //some condition

                    ) {
                      console.log(result[i].products[j].productCode);
                    }
                  }
                }else {
                  console.log('No data found');
                  return;
                }
              }
            }
          });
        });
      }
    } catch (err) {
      console.error(err);
    }
  }
}

答案

原始答案

如果您的try块失败,您将不会返回任何内容。但是您声明了方法的返回类型始终为Observable<any>类型。也可以从catch块中返回一个observable,或者将方法的返回类型声明为Observable<any> | void

尽管请注意,您的代码很可能无法按预期工作。在您的try块中,您正在使用for语句执行for循环。由于return语句退出了该函数,因此for循环实际上没有任何效果,因为它只会循环一次,然后立即从方法中返回。

详细说明您的观测值

您最可能想做的是以某种方式组合您的可观测对象。现在,有多种方法可以执行此操作,但是最简单的解决方案是将它们forkJoin。我建议您进一步阅读rxjs。其次,我强烈建议您在HttpClient中使用有角的HttpClientModule来执行HTTP请求(不用担心,如果您提供HTTPS URL,HttpClient会执行HTTPS请求。

您的代码可能看起来像这样:

import {Injectable} from '@angular/core';
import {HttpClient} from '@angular/common/http';
import {forkJoin, Observable, of} from 'rxjs'; 
import {map, catchError} from 'rxjs/operators';

@Injectable({
  providedIn: 'root'
})
export class MessageService {
  constructor(
    private readonly http:HttpClient
  ) {}


  publishMessages(productEvent: ProductEvent): Observable<Array<any>> { // Notice the return type is now an Array of all responses!
    let json = '';
    const url:string = 'some-url.com';
    const urls:Array<string> = [
      'https://' + url + '/blc',
      'https://' + url + '/eye'
    ];

    // Takes an array of observables and combines them into 1 which only emits when ALL observables inside complete,
    return forkJoin( 
      urls.map(urlToLoad => // Map your Array of URLs to an Array of Observables that do the HTTP(S) Request
        this.http.get(urlToLoad).pipe( // Create the HTTP Request per URL inside your array
          map(apiResult => { // apiResult is the result from your API Endpoint already parsed as a json Object
             // here you can transform your apiResult to any fitting object you want, if the json is already what you want, just leave the whole map function out
             return apiResult;
          }),
          catchError(err => { // This is run when the API call failed for some reason (e.g. http code >= 400)
            console.log(err); 
            return of(null); // Transform the error to a positive response to not break the forkJoin, depends on how you want to handle your error though
          })
        )
      )
    );
  }
}

以上是关于如何将Observable设置为void?的主要内容,如果未能解决你的问题,请参考以下文章

RxJS:如何将 Observable<Observable<Thing>> 转换为 Observable<Thing[]>

如果没有可用的互联网,如何将 ContentView 设置为另一个片段,如果连接可用,如何恢复片段

如何仅将应用程序片段设置为纵向模式?

如何将选定的对话框值设置为片段中的 TextViews [重复]

如何在 RxSwift 中取消订阅 Observable?

如何将 Observable 转换为 ReplaySubject?