等待方法的响应,然后再继续而不使用 SJAX

Wait for method's response before continuing without using SJAX

本文关键字:SJAX 再继续 然后 方法 响应 等待      更新时间:2023-09-26

我有一个应该返回特定值的方法,并且可以在一次页面加载中多次调用。需要返回的值只能通过 S/AJAX 访问,因此在第一次找到它后,它会存储在一个值中以供将来检索。

var dynamo = {
    stored_val : 0,
    get : function() {
        if(stored_val === 0) {
            $.ajax({
                url : 'URL'
                success : function(r) {
                    dynamo.stored_val = r;
                    // I want to return this value here now!
                }
            });
        } else {
            return dynamo.stored_val;
        }
    }
};

如您所见,我想使用 dynamo.get 并在继续执行其余代码之前使其返回值易于访问。我知道 SJAX,但由于它已被弃用,我宁愿不使用它。我研究了jQuery的承诺,允许方法推迟到操作完成,也许可以在这里使用?我已经调查过了,但找不到任何方法。如果它允许我做这样的事情:

dynamo.get().done(function(r) {
    // everything else here
    // r = the value of dynamo.stored_val after .get() and all AJAX calls within have completed
});

这可能吗?

我知道我可以简单地从.get()中提取方法并将其与回调一起使用,但是我的代码中有多个点可以随时调用.get()(基于用户活动),我不想到处写回调。

如果您需要更多信息,请告诉我!

请求存储在某个地方,以便在尚未完成时返回挂起的请求,这样只会发出一个请求,并且结果被缓存以供以后调用get()

var dynamo = {
    xhr        : null,
    stored_val : 0,
    get        : function() {
        if( this.stored_val === 0 && this.xhr === null) {
            this.xhr = $.ajax({ url : 'URL', context : this }).always(function(res) {
                this.xhr = null;
                this.stored_val = res;
            })
        } else if (this.xhr === null) {
            this.xhr = (new $.Deferred()).resolve(this.stored_val);
        }
        return this.xhr;
    }
};

然后你可以做

dynamo.get().done(fn).fail(err);

"承诺"存储在stored_val中 - 然后.get将始终返回相同的东西,即"承诺",并且您像使用任何其他承诺一样使用它...与.then(不确定.done在jquery中做了什么,即底层Promise有什么副作用吗?如果没有,那么使用.done而不是.then。

var dynamo = {
    stored_val : 0,
    get : function() {
        if(dynamo.stored_val === 0) {
            dynamo.stored_val = $.ajax({
                url : 'URL'
            });
        }
        return dynamo.stored_val;
    }
};
dynamo.get().then(function(result) {
    // do something with result
});

就个人而言,我发现这样的对象有点麻烦,尤其是当它们还有很多东西时 - 我更喜欢将 IIFE 用于此类代码

var dynamo = (function() {
    var stored_val;
    return {
        get : function() {
            return stored_val = (stored_val === undefined) ? $.ajax({ url : 'URL' }) : stored_val;
        }
    };
}());

甚至更干净

var dynamo = (function() {
    var stored_val;
    return function() {
        return stored_val = (stored_val === undefined) ? $.ajax({ url : 'URL' }) : stored_val;
    };
}());

但是,在最后一种情况下,用法是

dynamo().then(...);

不需要get(),dynamo 现在是一个函数