У меня есть служба Angular 2, которая использует веб-службу SOAP. Для этого я использую клиент SOAP Javascript с функцией обратного вызова. Я знаю, что результатом служебного метода может бытьObservable
или aPromise
, но я не знаю, как перейти от функции обратного вызова обратно к службе.
Вот мой текущий код:
import { Injectable } from '@angular/core';
declare var SOAPClient: any;//<-- The library I'm using, it doesn't have types
@Injectable()
export class SoapService {
connection_url: Map<string,string>;
constructor() {
this.connection_url = new Map<string, string>();
this.connection_url.set('Example', 'http://localhost:8080/MYAPP_EJB/ExampleSvc');
}
consume(service_name: string, method: string, parameters?: Map<string,any>){
var that = this;
return new Promise<any>(function(resolve){
var params = new SOAPClientParameters();
if(parameters !== null){
for (let parameter of parameters.keys()){
params.add(parameter,parameters.get(parameter));
}
}
//Below is the line where I use the function with the callback function argument (function(j)), where j represents the response from the Web Service
SOAPClient.invoke(that.connection_url.get(service_name), method,params,true,
function(j){
return new Promise<any>(function(resolve){
console.log('Web Service Answer: ' + j.answer.entry.value);
return j;
});
}); //End of SOAPClient.invoke()
}); //End of promise of consume()
}//End of consume()
}//End of class
Что я могу сделать, чтобы функция consumer () предоставила компоненту ответ веб-службы? Потребуется ли мне внести некоторые изменения в SOAPClient?
Спасибо.
Изменить: решение
Я использовал ответ Робина и работал сbindCallback
(та же идея, что иfromCallback
, см. bindCallback для справки), используя SOAPClient.invoke
в качестве аргумента для этой функции. Результирующая функция такая же, как и исходная, но без функции обратного вызова, вместо этого возвращая aObservable
, на который я могу подписаться, а затем выполнить обещание ofconsume()
.
Новый код:
import { Injectable } from '@angular/core';
import * as Rx from "rxjs";
declare var SOAPClient: any;//<-- The library I'm using, it doesn't have types
@Injectable()
export class SoapService {
connection_url: Map<string,string>;
invokeSoapClient: any;
constructor() {
this.connection_url = new Map<string, string>();
this.connection_url.set('Example', 'http://localhost:8080/MYAPP_EJB/ExampleSvc');
this.invokeSoapClient = <any> Rx.Observable.bindCallback(SOAPClient.invoke);
}
consume(service_name: string, method: string, parameters?: Map<string,any>){
var that = this;
return new Promise<any>(function(resolve){
var params = new SOAPClientParameters();
if(parameters !== null){
for (let parameter of parameters.keys()){
params.add(parameter,parameters.get(parameter));
}
}
var invokeObs = that.invokeSoapClient(that.conexion_url.get(service_name), method, params, true);
invokeObs.subscribe(r => {resolve(r[0])}); //r is the answer from SOAPClient invoke, I just needed the response part.
}); //End of promise of consume()
}//End of consume()
}//End of class