【问题标题】:Is there any alternative to this error - A function whose declared type is neither 'void' nor 'any' must return a value?是否有任何替代此错误的方法 - 声明类型既不是“void”也不是“any”的函数必须返回一个值?
【发布时间】:2019-12-13 18:22:30
【问题描述】:

我正在使用 Observable 从 Http 端点获取数据。如果我没有在这一行 return https.get(urls[i], res => 中添加 return 语句,我会收到此错误 A function whose declared type is neither 'void' nor 'any' must return a value.。在此处添加 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);
    }
  }
}

【问题讨论】:

  • 如果您不希望函数返回任何内容,为什么还要声明该函数具有void 以外的返回类型?
  • 我不知道如何在此处提及void
  • publishMessages(productEvent: ProductEvent): void 应该是你的第一次尝试
  • 不使用 Observable 我在 JSON.parse 中遇到语法错误。看起来 observable 是必须的。还有其他建议吗?
  • 您实际上想在这里做什么?我对内部带有 return 的 for 循环特别好奇。那一定是搞错了???

标签: node.js typescript


【解决方案1】:

原答案

如果您的 try 块失败,您将不会返回任何内容。但是您声明您的方法返回类型始终为Observable&lt;any&gt; 类型。要么从你的 catch 块中返回一个 observable,要么将方法返回类型声明为 Observable&lt;any&gt; | void

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

详细说明您的 Observables

您最可能想做的是以某种方式组合您的可观察对象。现在,有多种方法可以做到这一点,但最简单的解决方案是forkJoin 他们。我建议您多阅读rxjs。 其次,我强烈建议您使用 HttpClientModule 中的角度 HttpClient 来执行 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,以便它循环通过第二个端点,但在这样做之后,我从第一个端点获取数据,然后收到此错误 SyntaxError: Unexpected token [ in JSON at position 18140295 at JSON.parse (&lt;anonymous&gt;)。有什么建议吗?
  • @osama 我更新了我的答案,以提供更多关于如何解决您的问题的解释。您收到的错误消息很可能是因为您的所有 API 请求都写入同一个 json 对象,因此结果不是正确的 json - 毕竟每个请求都写入同一个对象。如果你使用 Angular HttpClient,这个问题会为你解决。
猜你喜欢
  • 2019-01-06
  • 2018-03-18
  • 2018-03-09
  • 1970-01-01
  • 2021-12-01
  • 1970-01-01
  • 2017-06-12
  • 2018-03-15
  • 2015-06-29
相关资源
最近更新 更多