admin管理员组

文章数量:1317906

In my script, I need to retrieve a dictionary to convert encoded values into names:

$.ajax({
    // retrieve dictionary
})
.done(function(dictionary){
    // convert encoded values into names
})
.done(function(){
    // run my application
});

However, sometimes the dictionary has already been loaded by another application, and in this case I don't need the ajax call:

if (dictionary) {
    // convert encoded values into names
    // run my application
}
else {
$.ajax({
    // retrieve dictionary
})
.done(function(dictionary){
    // convert encoded values into names
})
.done(function(){
    // run my application
});
}

This if/else statement is rather heavy, is there a way to make it shorter:

// load dictionary if needed
// then run my application

Note: I used the $ sign for my pseudo-code, but I am not necessarily tied to jQuery.

In my script, I need to retrieve a dictionary to convert encoded values into names:

$.ajax({
    // retrieve dictionary
})
.done(function(dictionary){
    // convert encoded values into names
})
.done(function(){
    // run my application
});

However, sometimes the dictionary has already been loaded by another application, and in this case I don't need the ajax call:

if (dictionary) {
    // convert encoded values into names
    // run my application
}
else {
$.ajax({
    // retrieve dictionary
})
.done(function(dictionary){
    // convert encoded values into names
})
.done(function(){
    // run my application
});
}

This if/else statement is rather heavy, is there a way to make it shorter:

// load dictionary if needed
// then run my application

Note: I used the $ sign for my pseudo-code, but I am not necessarily tied to jQuery.

Share Improve this question asked Sep 30, 2013 at 16:47 ChristopheChristophe 28.2k29 gold badges102 silver badges143 bronze badges 3
  • 1 I do this sort of thing quite a lot in my applications. The thing you have you get your mind round is that if data is acquired asynchronously then you MUST access it with asynchronous methods regardless of whether it is already acquired or not - reason being at each and every usage, you don't know whether the data is immediately available or whether it needs to be fetched. – Beetroot-Beetroot Commented Sep 30, 2013 at 22:05
  • @Beetroot-Beetroot could you explain how you access already acquired data with asynchronous methods? Maybe post an answer with code or pseudo-code? – Christophe Commented Sep 30, 2013 at 22:14
  • See the answers already posted. That's what the guys are trying to explain. – Beetroot-Beetroot Commented Sep 30, 2013 at 22:15
Add a ment  | 

3 Answers 3

Reset to default 3

You should call $.ajax() exactly once, and store the returned promise in your (global-ish) dictionary variable.

Then, every time you want to use the result, just write dictionary.then(...).
If the AJAX request already finished, the callback will run immediately.

This is the pattern I generally use:

var done = function() {
    //continue loading application
}

if(!dictionary) {
    $.ajax({

    })
        .done(done);
} else {
    done.apply(this);
}

A very similar pattern, that always makes use of a deferred object, could be the following:

var 
    dictionaryDeferred = new $.Deferred(),
    dictionaryPromise = dictionaryDeferred.promise();

if(!dictionary) {
    $.ajax({

    })
        .done(function() {
            //do something with the response
            dictionaryDeferred.resolve();
        });
} else {
    dictionaryDeferred.resolve();
}

dictionaryPromise.then(function() {
    //continue loading application
});

Maybe create a bogus promise with $.when?

var promise;
if (dictionary) promise = $.when(dictionary);
else {
    promise = $.ajax({

    })
    .done(function(dictionary){
        // convert encoded values into names
    });
}

promise
    .done(function(){
        // run my application
    });

本文标签: javascriptConditional promisesStack Overflow