nestjs中的Observables-异步读取文件 [英] Observables in nestjs - Reading a file asynchronously

查看:241
本文介绍了nestjs中的Observables-异步读取文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试一个用例,它以异步方式读取json文件并将其作为响应(作为rxjs可观察的数据)发送出去.这是我使用的服务

I am trying a use case of reading a json file asynchronously and sending it out as a response (as a rxjs observable data). Here is the service that I use

 import { logger } from './../../shared/utils/logger';
import { Injectable } from '@nestjs/common';
import * as fs from 'fs';
import * as path from 'path';
import { BehaviorSubject, Observable, pipe, of, from, throwError, merge} from 'rxjs';
import { map, filter, scan, take, debounce, switchMap, retry, catchError, mergeMap, delay, zip, tap, mapTo } from 'rxjs/operators';
import { HttpResponseModel } from '../model/config.model';
import { isNullOrUndefined } from 'util';
@Injectable()
export class NewProviderService {
    serviceSubject: BehaviorSubject<HttpResponseModel[]>;
    filePath: string;
    httpResponseObjectArray: HttpResponseModel[];
    constructor() {
        this.serviceSubject = new BehaviorSubject<HttpResponseModel[]>([]);
        this.filePath = path.resolve(__dirname, './../../shared/assets/httpTest.json');
        this.setSubject();
    }


 readFileFromJSON() {
      this.readFileFromJsonSync();
      fs.exists(this.filePath.toString(), exists => {
        if (exists) {
           fs.readFile(this.filePath.toString(), 'utf-8', (err, data) => {
                logger.info('file read without parsin', data);
                this.httpResponseObjectArray = JSON.parse(data).HttpTestResponse;
                logger.info('array obj is:', this.httpResponseObjectArray);
                logger.info('file read after parsing', JSON.parse(data));
                return this.httpResponseObjectArray;
            });
        } else {
            return null;
        }

    });
}


getObservable(): Observable<HttpResponseModel[]> {
       // create an observable
        // return Observable.create(observer => {
        //     observer.next(this.readFileFromJSON());
        // });

        return of(this.readFileFromJsonSync()).pipe(map(data => {
            logger.info('inside obs methid', data);
            return data;
        }));

    }

    setSubject() {
        this.getObservable().subscribe(data => {
            logger.info('data before setting in sub', data);
            this.serviceSubject.next(data);
        });
    }
}

所以我想订阅这个在控制器中发出的可观察到的东西,但是订阅并读取了主题(BehaviorSubject)之后,这些值就被读取了.我了解我在订阅和发送数据方面做错了一些事情,但是不知道我在哪里做错了.每次控制器打印未订阅的数据已预订" ,然后继续读取文件并发出可观察的

So I wanted to subscribe to this emitted observable in the controller, but the values are getting read after I have subscribed and read the subject (BehaviorSubject). I understand that I am kind of doing something wrong with the subscription and emitting of data, but couldn't understand where I am doing wrong. Every time the controller prints 'data subscribed undefined' and then continues to read the file and emit the observable

这是控制器数据

@Get('/getJsonData')
  public async getJsonData(@Req() requestAnimationFrame, @Res() res) {
    this.newService.serviceSubject.subscribe(data => {
      logger.info('data subscribed', data);
      res.status(HttpStatus.OK).send(data);
    });

  }

如果我同步读取文件,效果很好

It works well if I read the file synchronously

使用以下方法替换readFileFromJSON(),效果很好

replace readFileFromJSON() with the following method and it works well

readFileFromJsonSync(): HttpResponseModel[] {
        const objRead = JSON.parse(fs.readFileSync(this.filePath.toString(), {encoding: 'utf-8'}));
        logger.info('object read is', objRead.HttpTestResponse);
        return objRead.HttpTestResponse;

    }

因此,我在异步读取文件时丢失了某些内容.我不确定我在做什么错.有人可以帮忙吗?

So I am missing something while reading the file async. I am not sure what am I doing wrong. Could someone please help?

推荐答案

问题是您实际上并没有在readFileFromJSON中返回任何内容.它将异步运行fs.existsfs.readFile以及相应的回调,但是回调的结果将被忽略.

The problem is that you don't actually return anything in readFileFromJSON. It will asynchronously run fs.exists and fs.readFile and the corresponding callbacks but the result from the callbacks is ignored.

您应该改用Promises.您可以自己创建Promise,也可以使用诸如bluebird之类的库将fs从基于回调的API转换为基于Promise的API.有关更多信息,请参见此线程.

You should use Promises instead. You can either create a Promise yourself or use a library like bluebird that transforms fs from a callback based API to a Promise based API. For more information see this thread.

return new Promise(function(resolve, reject) {
    fs.readFile(this.filePath.toString(), 'utf-8', (err, data) => {
        if (err) {
            reject(err); 
        } else {
            const httpResponseObjectArray = JSON.parse(data).HttpTestResponse;
            resolve(httpResponseObjectArray);
        }
    });
});

这篇关于nestjs中的Observables-异步读取文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆