使用 jQuery.ajax deferred with typescript 和自动响应处理
Use jQuery.ajax deferred with typescript and auto response handling
我对 Promises、deferred 和所有类似的东西非常陌生,我正在尝试使用 jQuery 将我的旧习惯(回调地狱)改变为 Promises(我知道它不会尊重 Promise A+,但这不是重点。
我现在所做的是两者的结合,我正试图摆脱回调。我也在使用 TypeScript,但据我所知,它不应该相关。我只是给出合理的警告,代码不是纯 JS。
// TODO I provide the "done" and "fail" callback here, but I'd like to use .done and .fail instead, but I want them to be executed AFTER the automatic response handling.
WidgetContext.getContext(
function(data){
console.log(data)
},
function(error){
console.log(error)
}
);
// In WidgetContext class, TODO here I want to get rid of the callbacks as well.
public static getContext(done: any, fail: any): JQueryPromise<WidgetContext> {
return Payline.WebService.WidgetWSProxy.ajax(
'context1.json',
{
userId: 123456
},
done,
fail
);
}
// In WidgetWSProxy class, TODO here again, there should not be any callback.
public static ajax(method: string = '', data: any = {}, done?: any, fail?: any, options: JQueryAjaxSettings = WidgetWSProxy._defaultOptions): JQueryPromise<WidgetWSProxy>{
var url = WidgetWSProxy.buildUrl(WidgetWSProxy._url, method);
return WidgetWSProxy._ajax(url, data, done, fail, WidgetWSProxy._processAjaxResponseData, WidgetWSProxy._logId + ' ' + url, options);
}
// In AbstractHttpProxy class, TODO the only callback should be the responseHandler.
protected static _ajax(url: string, data: any, done?: any, fail?: any, responseHandler?: any, logId: string = AbstractHttpProxy._logId, options: JQueryAjaxSettings = AbstractHttpProxy._defaultOptions): JQueryPromise<AbstractHttpProxy>{
// On log la requête.
log.group(logId);
log.time(logId);
// Si aucun gestionnaire de réponse n'est correctement fourni, utilisation de celui par défaut.
if(!_.isFunction(responseHandler)){
responseHandler = AbstractHttpProxy._defaultResponseHandler;
}
// On injecte les data dans les options, on fait ainsi afin de cacher la logique jQuery pour ce paramètre particulier qui sera souvent utilisé.
options = _.merge(options, {data: data});
log.info('Requête HTTP envoyée: ' + JSON.stringify({
url: url,
options: options
}));
// On effectue l'appel ajax et on retourne une Promise jQuery.
return $.ajax(url, options)
// Succès
.done(function(data){
if(_.isFunction(done)){
responseHandler(url, data, true, function(data){
// TODO HERE I execute the "done" callback inside the done() function, but I should not. I just need to call the responseHandler and update the data so the next call to ".done()" would use the updated data, even though I define it when I call the "WidgetContext.getContext()" method.
done(data);
});
}else{
logMissingCallback(getCallerName());
}
})
// Erreur (connexion interrompue, 404, 500, peu importe)
.fail(function(error){
if(_.isFunction(fail)){
responseHandler(url, error, false, function(error){
// TODO Same stuff here, with the fail().
fail(error);
});
}else{
logMissingCallback(getCallerName());
}
})
// Sera toujours exécuté, peu importe ce qu'il se passe. (succès/erreur)
.always(function(){
log.timeEnd(logId);
log.groupEnd();
}
);
}
我的目标是隐藏使用代理 (WidgetWSProxy) 背后的一些逻辑,自动记录所有请求并处理 HTTP 响应以根据需要格式化它们,然后使用转换后的响应使用 .done
延迟函数。
它在这里工作,但如果我这样做,它不会在 .done
调用中记录更新的响应。
WidgetContext.getContext(
function(data){
console.log(data)
},
function(error){
console.log(error)
}
)
.done(function(data){
console.log('init')
console.log(data)
});
使用多年后,很难摆脱回调地狱的思维方式...感谢您的帮助!
then use the transformed response using .done
deferred function.
即使您正在使用 jQuery 延迟,您也应该习惯于始终且只使用 then
,因为它实际上确实让回调转换一个值 - 而 return 是一个转换后价值的可链接承诺。
It's hard to get rid of the callback hell way to think when you've used it for years...
- 从您的代码中删除所有 success/error 回调。全部。
- 每个执行异步操作的函数,因此它通常需要一个在最后调用一次的回调,应该 return 一个承诺。
例如,这也包括您的 responseHandler
- 如果它们是异步的,它们需要 return 承诺,而不是接受回调。您的代码将变为
WidgetContext.getContext().then(function(data){
console.log(data)
}, function(error){
console.log(error)
});
public static getContext(): JQueryPromise<WidgetContext> {
return Payline.WebService.WidgetWSProxy.ajax(
'context1.json',
{
userId: 123456
}
);
}
public static ajax(method: string = '', data: any = {}, options: JQueryAjaxSettings = WidgetWSProxy._defaultOptions): JQueryPromise<WidgetWSProxy>{
var url = WidgetWSProxy.buildUrl(WidgetWSProxy._url, method);
return WidgetWSProxy._ajax(url, data, WidgetWSProxy._processAjaxResponseData, WidgetWSProxy._logId + ' ' + url, options);
}
protected static _ajax(url: string, data: any, responseHandler?: any, logId: string = AbstractHttpProxy._logId, options: JQueryAjaxSettings = AbstractHttpProxy._defaultOptions): JQueryPromise<AbstractHttpProxy>{
if(!_.isFunction(responseHandler))
responseHandler = AbstractHttpProxy._defaultResponseHandler;
options = _.merge(options, {data: data});
log.group(logId);
log.time(logId);
log.info('Requête HTTP envoyée: ' + JSON.stringify({
url: url,
options: options
}));
return $.ajax(url, options).then(function(data){
return responseHandler(url, data, true);
}, function(error){
return responseHandler(url, error, false);
}).always(function(){
log.timeEnd(logId);
log.groupEnd();
});
}
我对 Promises、deferred 和所有类似的东西非常陌生,我正在尝试使用 jQuery 将我的旧习惯(回调地狱)改变为 Promises(我知道它不会尊重 Promise A+,但这不是重点。
我现在所做的是两者的结合,我正试图摆脱回调。我也在使用 TypeScript,但据我所知,它不应该相关。我只是给出合理的警告,代码不是纯 JS。
// TODO I provide the "done" and "fail" callback here, but I'd like to use .done and .fail instead, but I want them to be executed AFTER the automatic response handling.
WidgetContext.getContext(
function(data){
console.log(data)
},
function(error){
console.log(error)
}
);
// In WidgetContext class, TODO here I want to get rid of the callbacks as well.
public static getContext(done: any, fail: any): JQueryPromise<WidgetContext> {
return Payline.WebService.WidgetWSProxy.ajax(
'context1.json',
{
userId: 123456
},
done,
fail
);
}
// In WidgetWSProxy class, TODO here again, there should not be any callback.
public static ajax(method: string = '', data: any = {}, done?: any, fail?: any, options: JQueryAjaxSettings = WidgetWSProxy._defaultOptions): JQueryPromise<WidgetWSProxy>{
var url = WidgetWSProxy.buildUrl(WidgetWSProxy._url, method);
return WidgetWSProxy._ajax(url, data, done, fail, WidgetWSProxy._processAjaxResponseData, WidgetWSProxy._logId + ' ' + url, options);
}
// In AbstractHttpProxy class, TODO the only callback should be the responseHandler.
protected static _ajax(url: string, data: any, done?: any, fail?: any, responseHandler?: any, logId: string = AbstractHttpProxy._logId, options: JQueryAjaxSettings = AbstractHttpProxy._defaultOptions): JQueryPromise<AbstractHttpProxy>{
// On log la requête.
log.group(logId);
log.time(logId);
// Si aucun gestionnaire de réponse n'est correctement fourni, utilisation de celui par défaut.
if(!_.isFunction(responseHandler)){
responseHandler = AbstractHttpProxy._defaultResponseHandler;
}
// On injecte les data dans les options, on fait ainsi afin de cacher la logique jQuery pour ce paramètre particulier qui sera souvent utilisé.
options = _.merge(options, {data: data});
log.info('Requête HTTP envoyée: ' + JSON.stringify({
url: url,
options: options
}));
// On effectue l'appel ajax et on retourne une Promise jQuery.
return $.ajax(url, options)
// Succès
.done(function(data){
if(_.isFunction(done)){
responseHandler(url, data, true, function(data){
// TODO HERE I execute the "done" callback inside the done() function, but I should not. I just need to call the responseHandler and update the data so the next call to ".done()" would use the updated data, even though I define it when I call the "WidgetContext.getContext()" method.
done(data);
});
}else{
logMissingCallback(getCallerName());
}
})
// Erreur (connexion interrompue, 404, 500, peu importe)
.fail(function(error){
if(_.isFunction(fail)){
responseHandler(url, error, false, function(error){
// TODO Same stuff here, with the fail().
fail(error);
});
}else{
logMissingCallback(getCallerName());
}
})
// Sera toujours exécuté, peu importe ce qu'il se passe. (succès/erreur)
.always(function(){
log.timeEnd(logId);
log.groupEnd();
}
);
}
我的目标是隐藏使用代理 (WidgetWSProxy) 背后的一些逻辑,自动记录所有请求并处理 HTTP 响应以根据需要格式化它们,然后使用转换后的响应使用 .done
延迟函数。
它在这里工作,但如果我这样做,它不会在 .done
调用中记录更新的响应。
WidgetContext.getContext(
function(data){
console.log(data)
},
function(error){
console.log(error)
}
)
.done(function(data){
console.log('init')
console.log(data)
});
使用多年后,很难摆脱回调地狱的思维方式...感谢您的帮助!
then use the transformed response using
.done
deferred function.
即使您正在使用 jQuery 延迟,您也应该习惯于始终且只使用 then
,因为它实际上确实让回调转换一个值 - 而 return 是一个转换后价值的可链接承诺。
It's hard to get rid of the callback hell way to think when you've used it for years...
- 从您的代码中删除所有 success/error 回调。全部。
- 每个执行异步操作的函数,因此它通常需要一个在最后调用一次的回调,应该 return 一个承诺。
例如,这也包括您的 responseHandler
- 如果它们是异步的,它们需要 return 承诺,而不是接受回调。您的代码将变为
WidgetContext.getContext().then(function(data){
console.log(data)
}, function(error){
console.log(error)
});
public static getContext(): JQueryPromise<WidgetContext> {
return Payline.WebService.WidgetWSProxy.ajax(
'context1.json',
{
userId: 123456
}
);
}
public static ajax(method: string = '', data: any = {}, options: JQueryAjaxSettings = WidgetWSProxy._defaultOptions): JQueryPromise<WidgetWSProxy>{
var url = WidgetWSProxy.buildUrl(WidgetWSProxy._url, method);
return WidgetWSProxy._ajax(url, data, WidgetWSProxy._processAjaxResponseData, WidgetWSProxy._logId + ' ' + url, options);
}
protected static _ajax(url: string, data: any, responseHandler?: any, logId: string = AbstractHttpProxy._logId, options: JQueryAjaxSettings = AbstractHttpProxy._defaultOptions): JQueryPromise<AbstractHttpProxy>{
if(!_.isFunction(responseHandler))
responseHandler = AbstractHttpProxy._defaultResponseHandler;
options = _.merge(options, {data: data});
log.group(logId);
log.time(logId);
log.info('Requête HTTP envoyée: ' + JSON.stringify({
url: url,
options: options
}));
return $.ajax(url, options).then(function(data){
return responseHandler(url, data, true);
}, function(error){
return responseHandler(url, error, false);
}).always(function(){
log.timeEnd(logId);
log.groupEnd();
});
}