1

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

这就是问题所在。

如果getData()使用承诺一切都按预期工作,并且在我的应用程序启动时,我会加载并显示对数据库的查询结果。

使用承诺的 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);
      });
    })
  }

}

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

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);
  }
}

我在启动时在我的应用程序中得到什么 在此处输入图像描述

关于为什么会发生这种情况的任何提示?我不认为这是正常行为,并认为这与我创建 observable 的方式有关。我已经阅读了有关bindCallback()操作员的信息,它的功能似乎是我在这里需要的,因为db.find()它是一个回调函数,但我无法正确实现它。

抱歉代码混乱,提前致谢

编辑 - 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 毫秒左右调用它,它会按预期返回查询。

4

1 回答 1

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

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

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

一个可观察的类似 promise 的运行异步独立于你的主线程。

于 2017-09-18T08:51:34.227 回答