回调函数使用promises而不是observables

时间:2017-09-18 07:01:10

标签: angular typescript observable reactive-programming nedb

在我的项目中,我有一个从NeDB加载数据的服务。为此,我有一个方法getData()。在我的组件中,使用ngOnInit()挂钩我调用此方法。

问题所在。

如果getData()使用promises,一切都按预期工作,并且在我的应用启动时,我有查询到加载和显示的数据库的结果。

使用承诺的getData()

import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Rx';

import * as Datastore from 'nedb';
import * as path from 'path';

@Injectable()
export class SearchService {
db: any;
  constructor() {
    this.db = new Datastore( {
      filename: path.resolve('src/assets/db.json'),
      autoload: true,
    });
  }

  getData(){
    return new Promise((resolve, reject) => {
      this.db.find({}, (err, docs) => {
        if (err) reject(err);
        resolve(docs);
      });
    })
  }

}

但如果我尝试使用observable执行此操作,则不会加载和显示任何内容(传递给订阅者的结果为undefined)。

使用observables的getData()

  getDataObs(){
    return new Observable(subscriber => {
      this.db.find({}, (err, docs) => {
        if (err) subscriber.error(err);
        subscriber.next(docs);
      })
    })
  }

应用组件

import { Component, OnInit } from '@angular/core';
import { SearchService } from './search_service/search.service';
import { Observable } from 'rxjs/Observable';
import * as Datastore from 'nedb';
import * as electron from 'electron';
import * as path from 'path';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
  providers: [SearchService]
})
export class AppComponent implements OnInit {
  title = 'app';
  datum;
  res;
  constructor(private searchService: SearchService){ }
  ngOnInit(){
    this.getData();
    this.res = this.searchService.getDataObs();
  }

  getData(){
    this.searchService.getData().then(res => this.datum = res);
  }
}

启动时我在应用中获得的内容 enter image description here

有关为什么会发生这种情况的提示?我不认为这是正常的行为,并假设它与我创建可观察的方式有关。我已经阅读了bindCallback()运算符,其功能似乎就是我需要的,因为db.find()是一个回调函数,但我无法正确实现它。< / p>

对于凌乱的代码感到抱歉,并提前致谢

编辑 - HTML

<!--The whole content below can be removed with the new code.-->
<div style="text-align:center">
  <h1>
    Welcome to {{title}}!!
    Data: {{datum}}
    Res: {{res | async}}
  </h1>

编辑 - 如果我将getDataObs()方法添加到按钮,或者在启动后100个左右调用它,它会按预期返回查询。

1 个答案:

答案 0 :(得分:0)

this.res = this.searchService.getDataObs();

这个表达式只是将Observable实例返回到“res”,您可能需要做的是订阅此Observable并在成功回调中设置响应。正如你所提到的那样,当你在几毫秒后触发它时它会正常工作,因为那时呼叫已经完成。

this.searchService.getDataObs().subscribe(res => this.res = res)

一个可观察到的相似的promise与你的主线程异步运行。