2016-09-27 61 views
0

我正在創建一個將使用https://github.com/vpulim/node-soap與肥皂服務器進行通信的應用程序。導出變量,這是異步函數調用的結果

我想創建一個客戶端組件,我將把必要的方法轉發到使用此模塊創建的soap-client。

我無法返回將使用此客戶端的對象,因爲客戶端是異步創建的。

var soap = require('soap'); 
var url = 'http://someurl?wsdl'; 

soap.createClient(url, function(err, client) { 
    if (err) { 
     console.log(err); 
     return; 
    } 
    console.log(client.describe()); 
    // I need to publish this client so that other functions in this file will be able to use it 
}); 



module.exports = { 
    doSomething: function() { 
     //how can I access the client here? 
    } 
}; 

我該如何去做這件事?

回答

2

一個解決這個問題的方法是使用promises

var soap = require('soap'); 
var url = 'http://someurl?wsdl'; 

var clientPromise = new Promise(function(resolve, reject) { 
    soap.createClient(url, function(err, client) { 
     if (err) { 
      // reject the promise when an error occurs 
      reject(err); 
      return; 
     } 

     // resolve the promise with the client when it's ready 
     resolve(client); 
    }); 
}); 


module.exports = { 
    doSomething: function() { 
     // promise will wait asynchronously until client is ready 
     // then call the .then() callback with the resolved value (client) 
     return clientPromise.then(function(client) { 
      // do something with client here 
     }).catch(function(err) { 
      // handle errors here 
      console.error(err); 
     }); 
    } 
}; 

一些優勢,這一點:

  • 承諾是原生的JavaScript對象(如節點4.0.0的,有包,如bluebird爲以前版本提供支持)
  • 承諾可以「重用」:如果clientPromise已經解決一次,它會立即解決doSomething lat呃打電話。

一些缺點:

  • doSomething和所有其他導出函數本質上是異步的。
  • 不直接兼容節點類型的回調。
+0

我知道承諾,但沒有想到在每個函數內解決它們。這將做,謝謝:) –

0

不知道我的回答是否可以幫助你,但這是我的方式。我每次都創建createClient,然後在客戶端內部,我調用實際的SOAP方法(這裏是GetAccumulators)。可能不是一個好方法,但這對我很有用。這裏是我的代碼示例

soap.createClient(url, function (err, client) { 
    if (err) { 
    logger.error(err, 'Error creating SOAP client for %s', tranId); 
    reject('Could not create SOAP client'); 
    } 

    client.addSoapHeader(headers); 
    // envelope stuff 
    client.wsdl.definitions.xmlns.soapenv = 'http://schemas.xmlsoap.org/soap/envelope/'; 
    client.wsdl.definitions.xmlns.acc = 'http://exampleurl/'; 
    client.wsdl.xmlnsInEnvelope = client.wsdl._xmlnsMap(); 

    client.GetAccumulators(args, function (err, result) { 
    if (err) { 
     if (isNotFoundError(err)) { 
     logger.debug('Member not found for tranId %s', tranId); 
     reject({status:404, description:'No match found'}); 
     } 
     reject({status:500, description:'GetAccumulators error'}); 
    } 
    return resolve({data: result, tranId: tranId}); 
    });