2016-09-27 2 views
0

Я создаю приложение, которое будет использовать https://github.com/vpulim/node-soap для связи с мыльным сервером.Экспортировать переменную, которая является результатом вызова асинхронной функции

Я хотел бы создать клиентский компонент, который я буду перенаправлять необходимые методы на мыльный клиент, созданный с помощью этого модуля.

У меня возникли проблемы с возвратом объекта, который будет использовать этот клиент, поскольку клиент создается асинхронно.

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 (как в Node 4.0.0, с пакетами, такими как bluebird, обеспечивающий поддержку предыдущих версий)
  • Обещания могут быть «повторно использованы»: если clientPromise уже разрешен один раз, он сразу же разрешит, когда doSomething is lat позвонил.

Некоторые недостатки:

  • doSomething и все другие экспортируемые функции являются по своей сути асинхронными.
  • Не работает напрямую с обратными вызовами типа Node.
+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}); 
    });