我有一个angular2服务,我希望它能做到以下几点:
所以 - 实际上我有步骤1/2工作 - 但当然是所有' async'。所以正在发生的事情是在我的组件中我正在调用服务,其中this.ftp
是我服务的实例:
this.servers = this.ftp.lookForServers();
现在这正确地调用了我的FTP服务的lookForServers方法,如下所示:
lookForServers(){
var servers = [];
var whereAreWe = 0;
var possibles = ["/path/to/servers/"];
for(var i=0;i<possibles.length;i++){
whereAreWe = i;
this.c.list(possibles[i],false,(err,list)=>{
for(var p=0;p<list.length;p++){
console.log(list[p]);
var server_version = this.grabLog(possibles[whereAreWe]+list[p].name);
servers.push({
name: list[p].name,
path: possibles[whereAreWe]+list[p].name,
version: server_version
});
}
});
}
return servers;
}
现在 - this.grabLog(possibles[whereAreWe]+list[p].name);
函数调用最终进一步调用this.c - FTP客户端,当然是异步的,所以这个方法几乎立即返回 - 同时回调继续运行。那些回调下载一个文件,然后另一个回调函数处理这个文件 - 再次逐行,异步挑选我想要存储的各种细节。
在这个链的末尾 - 我在决赛中有我的所有细节:
lineReader.on('close', () => { function - but of course my `this.ftp.lookForServers();` function call has long gone....and the component is none the wiser.
那么我怎样才能让这项工作异步发生,并且在工作完成后仍然会将结果传回给组件我的结果JSON对象?这可能是一个非常简单的问题,关于如何将服务调用作为组件回调...?
答案 0 :(得分:2)
您不需要它同步运行。您应该使lookForServers(以及它正在使用的其他函数)使用observables,然后订阅结果如下:
this.ftp.lookForServers().subscribe((data) => { this.servers = data });
以下是实施:
const Client = require('ftp');
const fs = require('fs');
const readline = require('readline');
import { NextObserver } from 'rxjs/Observer';
import { Observable } from 'rxjs/Rx';
interface server {
name: string;
path: string;
version: string;
java_version: string;
}
export class FTPClient {
username: string;
password: string;
host: string;
port: number;
c: any;
constructor() {
}
init(username, password, host, port) {
console.log("initiating FTP connection to:" + host + "on port:" + port);
this.username = username;
this.password = password;
this.host = host;
this.port = port;
this.c = new Client();
console.log("Client created");
}
connect() {
console.log("About to start connection");
this.c.on('ready', () => {
this.c.list((err: any, list: any) => {
if (err) throw err;
console.dir(list);
this.c.end();
});
});
// connect to localhost:21 as anonymous
var connectProps = {
host : this.host,
port : this.port,
user : this.username,
password : this.password
};
console.log("Connecting now...");
this.c.connect(connectProps);
}
public lookForServers(name: string): Observable<any[]> {
return Observable.create((observer: NextObserver <any[]>) => {
let servers = [];
let whereAreWe = 0;
let possibles = [ "/path/to/servers/" ];
for (var i = 0; i < possibles.length; i++) {
whereAreWe = i;
this.c.list(possibles[ i ], false, (err: any, list: any) => {
for (var p = 0; p < list.length; p++) {
this.grabMessagesLog(possibles[ whereAreWe ] + list[ p ].name)
.subscribe((data: any) => {
let server_version = data;
servers.push({
name : list[ p ].name,
path : possibles[ whereAreWe ] + list[ p ].name,
version : server_version
});
observer.next(servers);
observer.complete();
}
);
}
});
}
});
}
grabMessagesLog(path): Observable<any> {
return Observable.create((observer: NextObserver <any>) => {
let result = '';
let unix = Math.round(+new Date() / 1000);
this.c.binary(function(err) {
console.log(err);
});
this.c.get(path + "/logs/messages.log", (err, stream) => {
if (err) throw err;
stream.once('close', () => {
this.c.end();
this.getServerMetadataFromMessagesLog(unix + "_messages.log")
.subscribe((data) => {
stream.pipe(fs.createWriteStream(unix + "_messages.log"));
observer.next(data);
observer.complete();
});
});
});
});
}
getServerMetadataFromMessagesLog(path): Observable<any> {
return Observable.create((observer: NextObserver <any>) => {
let lineReader = readline.createInterface({
input : fs.createReadStream(path)
});
let server_version = "";
let java_version = "";
let line_no = 0;
lineReader.on('line', function(line) {
line_no++;
console.log("line number is:" + line_no);
if (line.includes("STUFF") && line.includes("FLAG2") && line_no == 2) {
var first = line.split("FLAG2")[ 1 ];
var last = first.split(" (")[ 0 ];
var version = "FLAG2" + last;
this.server_version = version;
console.log("version is:" + version);
}
if (line.includes("java.version =")) {
var javav = line.split("java.version =")[ 1 ];
this.java_version = javav;
lineReader.close();
}
console.log('Line from file:', line);
});
lineReader.on('close', () => {
var res = {
version : server_version,
java_version : java_version
};
alert("RES IS:" + JSON.stringify(res));
observer.next(res);
observer.complete();
});
});
}
}
答案 1 :(得分:1)
尝试使用递归函数和Angular的$timeout函数
function recursiveWait(server_version){
if(server_version != null){
return;
}
$timeout(function(){recursiveWait()}, 500);
}
并将其放在这里:
console.log(list[p]);
var server_version = this.grabLog(possibles[whereAreWe]+list[p].name);
recursiveWait(server_version);
servers.push({
name: list[p].name,
这将询问var是否!= null
如果它相等,它会在 500ms 中再次调用该函数,如果它不是它将返回并退出该函数,让代码继续。