Search code examples
javascriptnode.jspromisebluebird

Node chain of promises and code readability


I'm trying to send several request/responses from a node server, and because they are async, I had to dive into and start learning promises. Im using bluebird and node as well as request to send requests.

Im looking to establish a certificate chain, and my server is acting trusted third party. I have the following

function send_certificates (addr) {
    return send_csr_request(addr)
    .then(function(csr) {
       return new Promise(function(resolve,reject) {
         resolve(sign_device_cert(csr))}
     )}).then(function(signed_cert) {
       return new Promise(function(resolve,reject) {
         //another resolve here?
         resolve(send_cert(signed_cert));
       })
    });
}

Ideally I would like to slap on another request to this "promise-chain", something like resolve(send_cert(caroot_cert)) and just generally be able to modify this chain of reqeust/responses a bit better. I feel like there is a lot of boilerplate code just to call these methods. Is there any other, more manageable and readable way to do this?

Also I'm not sure if I need to promisify all these methods? If, say, sign_device_cert returns a Promise, how do I chain it with .then() calls?


EDIT

Here is my function that sends off a request..

function send_ca_cert(cert) {

  const url_string = "http://myaddress.com";
  var request_options = {
    url : url_string,
    proxy : my_proxy,
    body: pki.certificateToPem(cert),
    headers: { "someHeader : "somevalue"}
  };
  return new Promise((resolve,reject) => {
    request.postAsync(request_options, function(error, response, body) {
      if (!error && response.statusCode == 200) {
        console.log("Sent off ca cert" );
        resolve();
      }
      reject();
    });
  });
}

When I call then(send_cert).then(send_ca_cert) i get the prints

Sent off ca cert
Sent off cert

How come they don't respect the Promises?


Solution

  • You don't have to wrap promises in promises. Do just

    function send_certificates (addr) {
        return send_csr_request(addr)
        .then(sign_device_cert)
        .then(send_cert);
    }
    

    This should work in your case (at least if your code works).

    Sometimes, you can't just pass the original function because it needs different arguments (or a different context). In those cases you still can avoid creating a new promise:

    return functionReturningAPromise()
    .then(otherFunctionReturningAPromise) // takes as parameter the result of the previous one
    .then(function(someValue){
        return yetAnotherFunctionReturningAPromise(22, someValue);
    });