Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 通用AJAX函数回调未按预期工作_Javascript_Jquery_Ajax - Fatal编程技术网

Javascript 通用AJAX函数回调未按预期工作

Javascript 通用AJAX函数回调未按预期工作,javascript,jquery,ajax,Javascript,Jquery,Ajax,我已经创建了通用ajax函数来使用RESTAPI 我已经写了下面的代码,它可以在一次调用中正常工作。但如果我做了两个不同的调用,那么我的成功回调将被最新的回调覆盖 var ajax = { parameters: { url: '', dataType: 'json', data: {}, contentType: 'application/json', loading: false, cro

我已经创建了通用ajax函数来使用RESTAPI

我已经写了下面的代码,它可以在一次调用中正常工作。但如果我做了两个不同的调用,那么我的成功回调将被最新的回调覆盖

var ajax = {
    parameters: {
        url: '',
        dataType: 'json',
        data: {},
        contentType: 'application/json',
        loading: false,
        crossDomain: true,
        async: true,
        timeout: 30000,
        otherData: {}
    },
    callback: {
        success: null,
        error: null
    },
    get: function () {
        this.send('GET');
    },
    post: function () {
        this.send('POST');
    },
    del: function () {
        this.send('DELETE');
    },
    send: function (type) {
        self = this;
        if (!navigator.userAgent.match(/iPad|iPhone|iPod|android|blackberry|IEMobile/i)) {
            this.loadingIcon.show();

            if (this.isUndefined(this.parameters.dataType)) this.parameters.dataType = 'json';
            if (this.isUndefined(this.parameters.contentType)) this.parameters.contentType = 'application/json';
            if (this.isUndefined(this.parameters.loading)) this.parameters.loading = false;
            if (this.isUndefined(this.parameters.crossDomain)) this.parameters.crossDomain = true;
            if (this.isUndefined(this.parameters.async)) this.parameters.async = true;
            if (this.isUndefined(this.parameters.timeout)) this.parameters.timeout = 30000;
            if (this.isUndefined(this.callback.error)) this.callback.error = this.defaultError;

            return $.ajax({
                type: type,
                url: this.parameters.url,
                dataType: this.parameters.dataType,
                data: JSON.stringify(this.parameters.data),
                contentType: this.parameters.contentType,
                crossDomain: this.parameters.crossDomain,
                async: this.parameters.async,
                timeout: this.parameters.timeout,
                success: function (data) {
                    var args = arguments[2];
                    if (!self.isUndefined(self.callback.success)) {
                        if (self.isUndefined(self.parameters.otherData))
                            self.callback.success.call(this, data, args.statusText, args);
                        else
                            self.callback.success.call(this, data, args.statusText, args, self.parameters.otherData);
                    }
                    self.loadingIcon.hide();
                },
                error: function (xhr, ajaxOptions, thrownError) {
                    xhrServerObj = xhr;
                    self.callback.error.call(xhr, ajaxOptions, thrownError);
                    self.loadingIcon.hide();
                }
            });
        }
    },
    isUndefined: function (param) {
        return (typeof param == 'undefined' || param == null);
    },
    defaultError: function (data, textStatus, jqXHR) {
    },
    loadingIcon: {
        show: function () {
            if (self.parameters.loading) {
                console.log('Show loading....');
            }
        },
        hide: function () {
            if (self.parameters.loading) {
                console.log('Hide loading....');
            }
        }
    }
}
function MyAjax() {
    this.parameters = {
        url: '',
        dataType: 'json',
        data: {},
        contentType: 'application/json',
        loading: false,
        crossDomain: true,
        async: true,
        timeout: 30000,
        otherData: {}
    };
    this.callback = {
        success: null,
        error: null
    };
    this.get = function () {
        this.send('GET');
    };
    this.post = function () {
        this.send('POST');
    };
    this.del = function () {
        this.send('DELETE');
    };
    this.isUndefined = function (param) {
        return (typeof param == 'undefined' || param == null);
    };
    this.defaultError = function (data, textStatus, jqXHR) {
    };
    this.loadingIcon = {
        show: function () {
            if (self.parameters.loading) {
                console.log('Show loading....');
            }
        },
        hide: function () {
            if (self.parameters.loading) {
                console.log('Hide loading....');
            }
        }
    };
    this.send = function (type) {
        self = this;
        if (!navigator.userAgent.match(/iPad|iPhone|iPod|android|blackberry|IEMobile/i)) {
            this.loadingIcon.show();

            if (this.isUndefined(this.parameters.dataType)) this.parameters.dataType = 'json';
            if (this.isUndefined(this.parameters.contentType)) this.parameters.contentType = 'application/json';
            if (this.isUndefined(this.parameters.loading)) this.parameters.loading = false;
            if (this.isUndefined(this.parameters.crossDomain)) this.parameters.crossDomain = true;
            if (this.isUndefined(this.parameters.async)) this.parameters.async = true;
            if (this.isUndefined(this.parameters.timeout)) this.parameters.timeout = 30000;
            if (this.isUndefined(this.callback.error)) this.callback.error = this.defaultError;

            return $.ajax({
                type: type,
                url: this.parameters.url,
                dataType: this.parameters.dataType,
                data: JSON.stringify(this.parameters.data),
                contentType: this.parameters.contentType,
                crossDomain: this.parameters.crossDomain,
                async: this.parameters.async,
                timeout: this.parameters.timeout,
                success: function (data) {
                    var args = arguments[2];
                    if (!self.isUndefined(self.callback.success)) {
                        if (self.isUndefined(self.parameters.otherData))
                            self.callback.success.call(this, data, args.statusText, args);
                        else
                            self.callback.success.call(this, data, args.statusText, args, self.parameters.otherData);
                    }
                    self.loadingIcon.hide();
                },
                error: function (xhr, ajaxOptions, thrownError) {
                    xhrServerObj = xhr;
                    self.callback.error.call(xhr, ajaxOptions, thrownError);
                    self.loadingIcon.hide();
                }
            });
        }
    }
}
我正在使用下面的命令进行ajax调用

getAllStores(); 
getAllCategory();

function getAllStores() {
    var req = Object.create(ajax);
    req.parameters = { url: API + '/api/mobileapp/stores' };
    req.callback.success = successGetAllStores;
    req.get();
}
function successGetAllStores(data) {
    $.each(data, function (idx, d) {
        $("#StoreId").append($("<option value='" + d.StoreId + "'>" + d.StoreName + "</option>"));
    });
}

function getAllCategory() {
    var req = Object.create(ajax);
    req.parameters = { url: API + '/api/mobileapp/categories' };
    req.callback.success = successGetAllCategory;
    req.get();
}
function successGetAllCategory(data) {
    $.each(data, function (idx, d) {
        $("#CategoryId").append($("<option value='" + d.CategoryId + "'>" + d.CategoryName + "</option>"));
    });
}
使用下面的调用

var aj1 = new MyAjax();
    aj1.parameters = { url: API + '/api/mobileapp/stores' };
    aj1.callback.success = successGetAllStores;
    aj1.get();

    var aj2 = new MyAjax();
    aj2.parameters = { url: API + '/api/mobileapp/categories' };
    aj2.callback.success = successGetAllCategory;
    aj2.get();

我想我可以看出您的问题所在-您在每次调用object.create时都使用相同的对象实例ajax作为原型,因此它们使用共享资源-因此对同一对象的后续调用会互相践踏

执行对象创建时,可以尝试使用$.extend。创建:

var clonedAjax = $.extend(true, {}, ajax);
var req = Object.create(clonedAjax);
然而,处理这段代码的一种更简洁的方法是使用ajax作为一个类,而不是使用object.create

function ajax(){
    this.parameters = {
        ....
    };
    this.get = function(){};
    .....
}
然后

更新:让它工作:从外观上看,这是一个范围问题,下面是一个简化的工作方法示例-关键是在成功发送和使用scb时分配scb。如果这不值得一个绿色勾号,那么什么都不值得;:


JavaScript中最合适的面向对象开发使用函数的原型

因此,首先创建一个函数:

Foo = function()
{
};
然后将函数添加到其原型中,如下所示:

Foo.prototype.Blah = function()
{
   // here you can access 'this'
};
现在Blah是名为Foo的对象/类的函数。您可以使用new关键字进行实例化,并按预期调用函数:

var f = new Foo;
f.Blah();
原型也可用于可变成员。JavaScript中有两种类型的变量成员:静态和非静态。如果您使用一个编译器,比如来自Google的闭包编译器,您也可以假装定义public、protected和private成员,但在最终版本中,所有内容都是public的

Foo.static_value = 123;  // initialized on load, common to all objects
Foo.prototype.value = 5; // initialized to 5 on construction
在大多数情况下,当静态变量为常量时,您希望使用静态变量

然而,可变成员存在一个陷阱。如果定义对象或数组,则不会复制这些对象或数组,因此相同的引用将显示在所有对象中。在大多数情况下,以下情况是错误的:

Foo.prototype.ary = [1, 2, 3];
Foo.prototype.obj = { a: 1, b: 2, c: 3 };
解决此问题的方法是在构造函数中初始化数组和对象,如下所示:

Foo = function()
{
  this.ary = [1, 2, 3];
  this.obj = { a: 1, b: 2, c: 3 };
};
Foo.prototype.Blah = function()
{
   this.ary.push(17); // not common to all objects of type Foo
};
然后,这些成员的声明使用null:

Foo.prototype.ary = null;
Foo.prototype.obj = null;
这样,您就避免了引用其他对象的问题,这对于您的所有对象来说都是公共的

您可能还希望使用名称空间,它只是一个变量,以避免以后出现潜在问题。假设您的库是call lib,您可以编写:

var lib = {};
然后将其作为所有Foo定义的前缀,如中所示:

lib.Foo = function() { ... };

也有从另一个对象派生一个对象的方法,但这更先进

通过学习如何使用$.extendHank进行解释,可以节省大量代码。我两种方法都试过了,但都不管用。1.使用$.extend时,我遇到一个错误,无法设置未定义的属性“success”。2.使用类函数,其行为与上面的原型对象相同,覆盖了最新的回调函数。更新后包含一个工作示例-如果您不介意一些建议的话-阅读jquery承诺,$.extend和truthy/falsy在评估是否存在某些东西时,您根本不需要这个未定义的函数。此外,如果您想使用这种方法,我建议使用IEFE声明ajax并关闭参数,更好的做法是使用类方法函数ajax{},而不是声明原型并使用object.create。嗯!
var lib = {};
lib.Foo = function() { ... };