使用promise对象重构jquery ajax调用

使用promise对象重构jquery ajax调用,jquery,Jquery,我正在使用身份验证进行异步跨域调用 当我通过身份验证后,我使用通用的get方法检索真实的应用程序数据: define(['jquery'], function ($) { return { get: function (url, data) { // Call to authenticate before retrieve data $.ajax({ type: 'POST',

我正在使用身份验证进行异步跨域调用

当我通过身份验证后,我使用通用的get方法检索真实的应用程序数据:

define(['jquery'], function ($) {
    return {
        get: function (url, data) {

            // Call to authenticate before retrieve data
            $.ajax({
                type: 'POST',
                url: 'root/authentication',
                data: { user: root: password: root },
                dataType: 'json',
                xhrFields: {
                    withCredentials: true
                },
                complete: function (response) {

                    // Call to retrieve application data
                    $.ajax({
                        beforeSend: function (xhr) {
                            xhr.withCredentials = true;
                        },
                        type: 'GET',
                        url: root + url,
                        xhrFields: {
                            withCredentials: true
                        },
                        async: true,
                        dataType: 'json',
                        crossDomain: true
                    });
                }
            });
        }
    };
});
上面的数据调用由另一个非通用代码调用:

define(['cors'],
    function(cors) {
        return function CustomerService() {            
            function getCustomers() {
                return cors.get('/customers');
            }
            return {
                getCustomers: getCustomers
            };
        };
    })
在我的knockoutjs viewmodel中,我希望执行以下操作:

当发出asyc调用时,执行renderConstomers函数并更新UI

 $.when(customerService.getCustomers())
            .done(renderCustomers)
            .fail();


        function renderCustomers(customers) {

            // Add data to knockout observables
        }
为了让我的客户使用RenderConstomers功能,我需要做哪些更改


现在客户还没有定义,我想这是因为我的ajax调用没有正确设置承诺。

在您的第一个代码片段中,您的ajax调用对成功的客户数据没有任何影响。试试这个:

define(['jquery'], function ($) {
    return {
        get: function (url, data) {
                var result = $.Deferred();  // create a deferred object to return
            $.ajax({
                type: "POST",
                url: 'root/authentication',   // you had a typo here
                data: { user: root: password: root },
                dataType: 'json',
                xhrFields: {
                    withCredentials: true
                },
                complete: function (response) {
                    // Call to retrieve application data
                    $.ajax({
                        beforeSend: function (xhr) {
                            xhr.withCredentials = true;
                        },
                        type: "GET",
                        url: root + url,
                        xhrFields: {
                            withCredentials: true
                        },
                        async: true,
                        dataType: 'json',
                        crossDomain: true
                    }).done(function(responseData){
                            // resolve the manually created deferred object, and send it the customer data
                        result.resolve(responseData);
                    });
                }
            });
            return result; // return your deferred object
        }
    };
});
请注意,在ajax上调用“done”与调用“success”是相同的。通过返回Deferred,您将能够使用cors.getCustomers()作为Deferred本身

您可以重构最后一个代码片段以删除“when”调用,并直接使用来自getCustomers的延迟代码,并将您的敲除绑定到那里:

customerService
    .getCustomers()  // this returns an deferred now so you can add done and fail events
  .done(function(customers) {

        // Add data to knockout observables
        var elem = document.getElementById('myelement');
        ko.applyBindings(customers,elem);
    });

您的
get
函数应该返回
$.ajax
,如
return$.ajax({…})
中所示。这将不起作用,因为他有嵌套的ajax调用。对于第二个ajax请求,我收到以下错误:“无法调用未定义的方法‘done’”。试着改用success,看看会发生什么。您正在使用哪个版本的jquery?getCustomers()上的v1.9.1和.success。success(…)和cors中的都不起作用。未定义成功。getCustomers()。成功(…)将不起作用,因为成功仅适用于ajax对象。所有ajax都是延迟的,但没有延迟的是ajax。但是,这个问题是第一个问题的次要问题,我们需要先解决它。好的,第一个问题已经解决了。我不知道为什么(玩得太多…),但现在我在cors和viewmodel中注册了.done():customerService.geCustomers().done(renderCustomers);