导出由异步函数调用导致的变量

时间:2016-09-27 20:38:02

标签: javascript node.js export

我正在创建一个使用https://github.com/vpulim/node-soap与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 个答案:

答案 0 :(得分: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);
        });
    }
};

这有一些好处:

  • Promise是本机JavaScript对象(从Node 4.0.0开始,其中bluebird等软件包支持以前的版本)
  • Promise可以“重复使用”:如果clientPromise已经解决了一次,则会在稍后调用doSomething时立即解决。

一些缺点:

  • doSomething和所有其他导出的函数本质上是异步的。
  • 与Node-type回调不直接兼容。

答案 1 :(得分: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});
  });