gpt4 book ai didi

javascript - 在不重构的情况下将 jQuery $.ajax 包装在 q.js 的外观后面

转载 作者:行者123 更新时间:2023-11-30 08:39:35 25 4
gpt4 key购买 nike

这可能应该进行代码审查,但我们开始吧!

我有一个相当大的应用程序,其中包含很多 ajax 调用。我开始将 Q 用于一些异步的东西,并想我会在 Q 中包装 ajax 调用以确保所有异步方法具有相同的签名。

我正在使用全局外观方法,因此我的 ajax 调用如下所示:

App.ajax( config ).then( doWhatever );

App.ajax 看起来像这样:

ajax: function( config ){
var ajaxReturn = $.ajax( config );
ajaxReturn.error(function( xhr ){
// some custom error handling
});
return ajaxReturn;
}

我将 App.ajax 修改为如下所示:

ajax: function( config ){
var dfd = Q.defer();
var ajaxReturn = $.ajax( config );
ajaxReturn.done(function( results, status, xhr ){
delete xhr.then;
dfd.resolve( results );
});
ajaxReturn.error(function( xhr ){
// some custom error handling
dfd.reject( "some message generated by error handling" );
});
return dfd.promise;
}

这有效,单个 ajax 调用本身需要 0 个更改,但它导致关心 $.ajax 返回的“状态”和“xhr”部分的 Ajax 调用停止工作。

我读过 Q's docs about coming from jQuery , 它基本上只是建议 "you should treat promise-returning functions like normal synchronous functions, in that you should assume they only return a single object"

现在,我不想重构所有关心 xhr 对象的调用以获取对象或使用 spread 代替 then/done。所以我在返回 Q promise 之前添加了这段代码:

dfd.promise.then = function( callback ){
dfd.promise.then = Q().then;
return dfd.promise.spread( callback );
};

并将我的解析行更改为:

dfd.resolve( [ results, status, xhr ] );

现在 App.ajax 看起来像这样:

ajax: function( config ){
var dfd = Q.defer();
var ajaxReturn = $.ajax( config );
ajaxReturn.done(function( results, status, xhr ){
delete xhr.then;
dfd.resolve( [ results, status, xhr ] );
});
ajaxReturn.error(function( xhr ){
// some custom error handling
dfd.reject( "some message generated by error handling" );
});
dfd.promise.then = function( callback ){
dfd.promise.then = Q().then;
return dfd.promise.spread( callback );
};
return dfd.promise;
}

因此,这是用一个包装函数覆盖了这个特定的 Deferred 的 then 函数,该函数将 then 重置为“真实的” then 并使用 spread 代替此调用。这导致我的应用程序 ajax 调用能够保留其原始签名,但仍然是一个彻头彻尾的 Q promise 。

这似乎工作正常,太棒了。

现在,终于可以回答问题了但这是否可取?我知道在自定义“then”方法中不必要地创建额外的 Promise 会对性能产生轻微影响。我不在乎那个。我更想知道是否有一些陷阱还没有让我上当,这绝对是一个非常糟糕的主意。

编辑:

上面的 block 有一些问题。这是最新、最正确的代码块。 promise 的 then 不能只是重置为“真实的”then,因为对初始 promise 的后续调用没有得到正确的传播结果,所以我们有将 then 方法重置为在返回新的传播 promise 之前调用传播的覆盖方法。

ajax: function( config ){
var dfd = Q.defer();
var ajaxReturn = $.ajax( config );
ajaxReturn.done(function( results, status, xhr ){
delete xhr.then;
dfd.resolve( [ results, status, xhr ] );
});
ajaxReturn.error(function( xhr ){
// some custom error handling
dfd.reject( "some message generated by error handling" );
});
var cachedThen = dfd.promise.then;
dfd.promise.then = function overrideThen( fulfilled, rejected ){
dfd.promise.then = cachedThen;
var spreadPromise = dfd.promise.spread( fulfilled, rejected );
dfd.promise.then = overrideThen;
return spreadPromise;
};
return dfd.promise;
}

最佳答案

你想多了。 Q 旨在与 jQuery promise 进行互操作。

如果你想将一个函数转换为返回一个 Q promise - 只需用 Q() 包装它:

myAjaxMethod(); // returns a jQuery promise
Q(myAjaxMethod()); // returns a Q promise that wraps the jQuery one

例如 - 您的 ajax 方法可以是:

function ajax(config){
return Q($.ajax(config));
}

哪个更短且更不容易出错。

关于javascript - 在不重构的情况下将 jQuery $.ajax 包装在 q.js 的外观后面,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27903781/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com