如何使AJAX同步

I know the nature of Ajax is the asynchronous, thus my code is wrong. But I need help to find another solution.

Case is: I insert data into my database with:

 self.insertTextItem = function (item) {
    console.log("Insert TextItem with Service");
    return $.ajax({    
        type: "POST",
        url: serviceRoot + "InsertTextbatchTagItem",
        beforeSend: serviceFramework.setModuleHeaders,
        data: item,
        cache: false
    });
};

item.Id = null; // Id is autocreated in db.
item.Text = "Finally Friday!";

self.insertTextItem(item)     
    .done(function (newtext) {
                item.textbatchId = newtext.Id;
}

//continuous code…

This works find in most cases. Exception is when I need the data returned from the database right away. However I need the "continuous code" to wait for the Id to be returned. The obvious solution is to place the "continuous code" into the callback-function, but as it is, I am calling self.insertTextItem in a function, thus the calling-function returns without waiting. (And obviously the callback function is ended within the calling function.)

How can I rewrite the self.insertTextItem-function in this case?

Exception is when I need the data returned from the database right away. However I need the "continuous code" to wait for the Id to be returned.

Your best bet is not to let that happen, but instead to embrace the event-driven, asynchronous nature of browser-based and network programming.

The very much lesser option is to force the ajax request to be synchronous. Currently, in jQuery 1.x, you can do that by adding async: false to your call; you'll also have to start using your own $.Deferred rather than the one you get from ajax, because as of jQuery 1.8, using async: false with the jqXHR's built-in promise is deprecated. So:

self.insertTextItem = function (item, synchronous) { // <== Optional flag
    var deferred = $.Deferred();                     // <== Your own Deferred
    console.log("Insert TextItem with Service");
    $.ajax({    
        type: "POST",
        url: serviceRoot + "InsertTextbatchTagItem",
        beforeSend: serviceFramework.setModuleHeaders,
        data: item,
        cache: false,
        async: synchronous === true ? false : true,  // <=== Use it, ignoring `undefined` and othe rfalsey values
        success: function(data) {                    // Handling you Deferred
            deferred.resolveWith(data);              // (this is probably incomplete)
        },                                           //
        error: function() {                          //
            deferred.reject();                       //
        }                                            //
    });
    return deferred.promise();                       // Return the promise for your Deferred
};

That will make insertTextItem block (locking up the UI of most browsers) until the call completes. Because of the way jQuery's promises work, that will also make the done callback synchronous. (This is not true of many other promises implementations, but it is of jQuery's.)

That option uses the underlying features of XMLHttpRequest, which allow for synchronous ajax.

That option will also be going away in jQuery at some point.

You can set the async property of $.ajax to false. By default it's true.

$.ajax({    
        type: "POST",
        async : false,
        url: serviceRoot + "InsertTextbatchTagItem",
        beforeSend: serviceFramework.setModuleHeaders,
        data: item,
        cache: false
    });