-1

Somewhere else in code there's this:

function getMyDeferred() {
    var deferred = $.Deferred();
    $.ajax(url, {
        success: function(data) {
            deferred.resolve(data);
        }
    });
    return deferred;
}

In my code, I'm accessing this method and getting a Deferred object. Is there any way to force it to wait at the current line until that deferred has been completed? I realize this is probably going against the whole philosophy of promises and deferreds, but can I do it? Something like this:

var deferred = getMyDeferred();

// do something here to ensure we do not proceed to the
// next step until deferred has been resolved

nextStep();
soapergem
  • 9,263
  • 18
  • 96
  • 152
  • Just use synchronous ajax instead? Ofc it is bad practice and not recommended, but if that's what you want.. – Fabrício Matté Oct 22 '14 at 23:45
  • Fabricio, for all intents and purposes, assume that I do not have access to change anything about the first block of code. All I have is the second. What I'm actually doing is unit testing so I need it to wait for a response before it can do anything with that response. – soapergem Oct 22 '14 at 23:46
  • 1
    Oh I see. Most unit test frameworks allow for asynchronous testing though. – Fabrício Matté Oct 22 '14 at 23:48
  • 1
    Is wrapping your code in `.then()` too much boilerplate? It's the generally accepted way of working with promises. – Kevin Ji Oct 22 '14 at 23:51
  • 1
    I think you can call defer.done(nextStep);. – MikeNQ Oct 22 '14 at 23:52
  • No. You can't make an async call wait until it's done. To use async, you have to learn how to code using async tools/techniques. Start learning. Also, you're using an anti-pattern with your `getMyDeferred()` function. You can just do `return $.ajax(...)` since it already returns a promise that is tied to the ajax call. – jfriend00 Oct 23 '14 at 00:09
  • @jfriend00 read his previous comments, he said he does not have control over that piece of code. – kennypu Oct 23 '14 at 00:48
  • @kennypu - He just says "somewhere else in code" and it's posted into his question. It's an anti-pattern no matter where it is so I think it is worth pointing that out in a comment for the benefit of the community. It's not like I said that was a solution to the problem. – jfriend00 Oct 23 '14 at 01:08
  • There is a way to accomplish what you want, but not when constrained to the way you want to do it. Ultimately, you shouldn't do it synchronously -- JavaScript doesn't work well this way. – robrich Oct 25 '14 at 01:52

3 Answers3

1

Try this:

getMyDeferred().done(nextStep);
Johan Karlsson
  • 6,419
  • 1
  • 19
  • 28
1

You are correct.

I realize this is probably going against the whole philosophy of promises and deferreds

But, you can use the option "async:false".

function getMyDeferred() {
    var deferred = $.Deferred();
    $.ajax(url, {
        async: false,
        success: function(data) {
            deferred.resolve(data);
        }
    });
    return deferred;
}

By jQuery documentation (http://api.jquery.com/jquery.ajax/)

By default, all requests are sent asynchronously (i.e. this is set to true by default). If you need synchronous requests, set this option to false. Cross-domain requests and dataType: "jsonp" requests do not support synchronous operation. Note that synchronous requests may temporarily lock the browser, disabling any actions while the request is active. As of jQuery 1.8, the use of async: false with jqXHR ($.Deferred) is deprecated; you must use the success/error/complete callback options instead of the corresponding methods of the jqXHR object such as jqXHR.done() or the deprecated jqXHR.success().

Wédney Yuri
  • 1,267
  • 12
  • 21
  • See my comment above explaining that, for all intents and purposes, I don't have access to modify that Ajax call. – soapergem Oct 23 '14 at 00:32
0

So after reading people's answers, comments, and doing more research myself, the answer to my original question is simply no, there isn't.

I appreciated Fabrício Matté's comments the most, which pointed out to me something I had just failed to notice at first glance: that the unit testing framework I'm using already has built-in options for asynchronous testing, so I don't need to do what I was outlining here.

soapergem
  • 9,263
  • 18
  • 96
  • 152