1
\$\begingroup\$

The below code uses Promises/A+ (specifically rsvp.js) to generate a token. It does so by either taking an existing token or downloading and parsing a token from a web page. Is it possible to chain this to LoadURIPromise more cleanly? Usually one can chain together promises without causing as much indentation drift.

new RSVP.Promise(function (resolve) {
    if (TokenData) {
        resolve(TokenData);
    } else {
        LoadURIPromise(TokenURL).then(function (xmlDoc) {
            TokenData = xmlDoc.evaluate(
                '/root/theToken', 
                xmlDoc.documentElement, 
                null, 
                XPathResult.FIRST_ORDERED_NODE_TYPE, 
                null
            ).singleNodeValue.textContent;
            resolve(TokenData);
        });
    }
}).then(function (token) {
    //Use Token here
}
\$\endgroup\$

2 Answers 2

2
\$\begingroup\$

I have never used RSVP, I am more familiar with Q, but I believe following should do what you need:

var evaluate = function (xmlDoc) {
    TokenData = xmlDoc.evaluate(
        '/root/theToken',
    xmlDoc.documentElement,
    null,
    XPathResult.FIRST_ORDERED_NODE_TYPE,
    null).singleNodeValue.textContent;
    return TokenData;
}

RSVP.resolve(TokenData || LoadURIPromise(TokenURL).then(evaluate))
    .then(function (token) {
    //Use Token here
    console.info(token);
});

Here is working jsFiddle

BTW, do you really need TokenData to be global?

\$\endgroup\$
2
  • \$\begingroup\$ TokenData is not global. The surrounding code looks something like Foo = function() {var TokenData; var checks = function() {/*Code in my question*/}} \$\endgroup\$
    – Brian
    Commented Aug 26, 2013 at 17:43
  • \$\begingroup\$ I'm not sure you are you going to use checks, but maybe you can also change TokenData to promise for token data: var TokenDataPromise = LoadURIPromise(TokenURL).then(evaluate); and shorten all that code to one line (except evaluate function). \$\endgroup\$
    – tomalec
    Commented Aug 29, 2013 at 23:25
0
\$\begingroup\$

I'm not familiar with the RSVP.js library. I use jQuery here, but the overall concept should still be (or exactly) the same:

// You can pull out your config to an array and use apply to use them
var config = [
  '/root/theToken',
  xmlDoc.documentElement,
  null,
  XPathResult.FIRST_ORDERED_NODE_TYPE,
  null
];

// So basically, the idea is the same, but we just pulled out some stuff
// - A ternary instead of an if statement
// - Removed the config to an array, and use apply to use them
$.Deferred(function (deferred) {
  TokenData ? deferred.resolve(TokenData) : LoadURIPromise(TokenURL).done(function(xmlDoc) {
    TokenData = xmlDoc.evaluate.apply(xmlDoc,config).singleNodeValue.textContent;
    deferred.resolve(TokenData);
  });
}).done(function (token) {
  /*We got token*/
})
\$\endgroup\$
1
  • 2
    \$\begingroup\$ Honestly, I find this harder to read. I'm not a fan of using the ternary operator as a replacement for conditionals except in very simple cases. Also, this has different semantics; it does not set TokenData. \$\endgroup\$
    – Brian
    Commented Aug 26, 2013 at 15:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.