如何使异步数据可观察?

时间:2016-12-30 15:27:10

标签: angular rxjs observable

新观察者。我正在使用ssh2来获取服务器上的文件/文件夹列表。由于所有在线使用http而不是第三方模块的例子,我无法弄清楚如何将我的数据作为一个可观察对象。

如何设置此服务以便我可以将列表作为可观察对象获取?

import {Injectable, NgZone} from '@angular/core';
import {Observable} from 'rxjs';
var Client = require('ssh2').Client;
var user = require('credentials.json')
@Injectable()
export class ConnectionService {
    public connSettings:any;

    constructor(private zone: NgZone){
        this.connSettings = {
            host: user.url,
            username: user.username,
            password: user.password
        };
        this.openConnection();

    }
    openConnection() {
        let remotePathToList = '/home/user';
        var conn = new Client();

        conn.on('ready', ()=>{
            conn.sftp((err:any, sftp:any)=>{
                if (err) throw err;
                sftp.readdir(remotePathToList, (err:any, list:any)=>{
                    conn.end();

                    //return observable data here

                    return list;

                })
            })
        }).connect(this.connSettings);

    }


}

1 个答案:

答案 0 :(得分:1)

如果您希望通用属性随时访问列表(与openConnection() - 方法无关),则可以使用ReplaySubject

@Injectable()
export class ConnectionService {
    public yourList$: ReplaySubject<any> = new ReplaySubject<any>(1);
    public connSettings:any;

    constructor(private zone: NgZone){
        this.connSettings = {
            host: user.url,
            username: user.username,
            password: user.password
        };
        this.openConnection();

    }
    openConnection() {
        let remotePathToList = '/home/user';
        var conn = new Client();

        conn.on('ready', ()=>{
            conn.sftp((err:any, sftp:any)=>{
                if (err) throw err;
                sftp.readdir(remotePathToList, (err:any, list:any)=>{
                    conn.end();

                    //return observable data here
                    yourList$.next(list);
                    return list;

                })
            })
        }).connect(this.connSettings);
    }
}

如果您只想将其作为openConnection的已退回Observable,则可以创建自定义Observable

@Injectable()
export class ConnectionService {
    public yourList$: ReplaySubject<any> = new ReplaySubject<any>(1);
    public connSettings:any;

    constructor(private zone: NgZone){
        this.connSettings = {
            host: user.url,
            username: user.username,
            password: user.password
        };
        this.openConnection();

    }
    openConnection(): Observable<any> {
        return Observable.create(obs => {
            let remotePathToList = '/home/user';
            var conn = new Client();

            conn.on('ready', ()=>{
                conn.sftp((err:any, sftp:any)=>{
                    if (err) throw err;
                    sftp.readdir(remotePathToList, (err:any, list:any)=>{
                        conn.end();

                        //return observable data here
                        obs.next(list);
                        obs.complete(); // required, otherwise your subscription would never close
                    })
                })
            }).connect(this.connSettings);
        });
    }
}

请注意,使用第二个解决方案,您必须在subscribe上调用openConnection,否则不会发生任何事情,因为它现在包含在一个可观察的内容中:

connectionService
    .openConnection()
    .subscribe(list => console.log(list));