用于处理成功、失败、重试的异步请求的设计模式?(JavaScript)
A design pattern for async requests to handle success, failure, retry ? (javascript)
我正在使用Appcelerator Titanium编写一个移动应用程序,该应用程序发出许多不同的xhr请求。这不是一个真正的Appcelerator Titanium特定问题。但是如果你确实写了一些代码,我希望它是javascript。
应用需要对自身进行身份验证,必须记录用户才能进行某些交互等。
我已经到了任何请求都可能得到任何类型的响应的地步,例如:
- 未通过身份验证
- 未记录
- 坏参数
- 成功的
- 。
请求包装在不同的模型方法或帮助程序中。
问题是,我不熟悉这种应用程序。我想知道什么是最佳实践。
例如,一些真正的问题是:
-
如果应用未通过身份验证(令牌已过期,首次启动),应用是否应尝试对自身进行身份验证,然后再次发送被拒绝的请求?(对用户透明)
-
我是否应该在每次应用程序启动时发送身份验证请求,然后"忘记"它?
我面临的问题是,如果我尝试为每个请求处理这个问题,代码很快就会变大。充满嵌套回调、重试条件、要管理的各种事件侦听器等。只是感觉不是很"好"。而且它根本不是 DRY,当我真正需要的是任何请求时,检查出了什么问题,尝试修复它(如果没有,则进行身份验证,如果可能的话自动登录或显示登录 UI 等),然后如果有效,请重试原始请求几次,如果需要,请中止。
我一直在研究承诺模式,但只知道理论,不知道它是否是我需要的。
因此,我欢迎有关此特定问题的任何建议。我想知道像"Facebook"这样的应用程序如何处理这个问题。
谢谢你的帮助
这个问题不容易回答,但让我试着给你一些想法:
在对应用进行任何编码之前,最重要的是 API 本身。它必须可靠并符合标准。我不会在这里详细介绍,但是一个编写良好的RESTful API可以显着降低httpClient的复杂性。它必须使用标准的http状态代码和诸如POST,GET,PUT,DELETE...
一个很好的读物是George Reese的The REST API设计手册。
我使用 Titanium 的 httpClients 的方法是单个模块,它在需要时通过 require() 加载。我一次坚持使用一个客户端,因为我在多个并行调用时遇到了大量问题。每当进行调用时,客户端都会检查是否已有正在进行的调用,并在必要时将其发送到队列。
我给大家举个例子。为了简洁起见,我省略了很多东西:
// lib/customClient.js
var xhrRequest; // This will be our HTTPClient
var callQueue = []; // This will be our queue
// Register the request
// params are:
// method (e.g. 'GET')
// url (e.g. 'http://test.com/api/v1/user/1')
// done (callback function)
function registerRequest(params) {
if(!xhrRequest) {
sendRequest(params);
} else {
queueRequest(params);
}
}
// This simply sends the request
// to the callQueue
function queueRequest(params) {
callQueue.push(params);
}
// Send the request with the params from register
// Please note that I do not hardcode error messages,
// I just do it here so it is easier to read
function sendRequest(params) {
// Set callback if available and valid
var callback = params.done && typeof(params.done) === "function" ? params.callback : null;
// Set method
var method = params.method || 'GET';
// Create the HTTP Client
xhrRequest = Ti.Network.createHTTPClient({
// Success
onload: function() {
// You can check for status codes in detail here
// For brevity, I will just check if it is valid
if (this.status >= 200 && this.status < 300) {
if(this.responseText) {
// You might want to check if it can be parsed as JSON here
try {
var jsonData = JSON.parse(this.responseText);
if(callback) callback({ success: true, response: jsonData });
} catch(e) {
if(callback) callback({ success: false, errormessage: 'Could not parse JSON data' });
}
processQueue();
} else {
if(callback) callback({ success: false, errormessage: 'No valid response received' });
processQueue();
}
} else {
if(callback) callback({ success: false, errormessage: 'Call response is success but status is ' + this.status });
processQueue();
}
},
// Error
onerror: function(e) {
if(this.responseText) {
try {
var jsonData = JSON.parse(this.responseText);
if(callback) callback({ success: false, reponse: jsonData });
} catch(e) {};
}
processQueue();
},
});
// Prepare and send request
// A lot more can (and should) be configured here, check documentation!
xhrRequest.setTimeout(10000);
xhrRequest.open(method, params.url);
xhrRequest.send();
}
// Checks if there is anything else in the queue
// and sends it
function processQueue() {
xhrRequest = null;
var nextInQueue = callQueue.shift();
if(nextInQueue) sendRequest(nextInQueue);
}
// Our public API
var publicAPI = {
sendRequest: function(params) {
registerRequest(params);
}
};
module.exports = publicAPI;
然后,我可以从任何其他控制器/视图发送呼叫
var customClient = require('lib/customClient'); // omit 'lib' if you use alloy
// Send the request
customClient.sendRequest({
method : 'GET',
url : 'http://test.com/api/v1/user/1',
done : function(response) {
Ti.API.debug(JSON.stringify(response));
}
});
请注意,这不完整,不会检查连接性,没有真正的错误处理等,但它可能会帮助您了解一些想法。
我认为这里有很多东西要谈,但我现在就到此为止......
- 用于操纵DOM API的Javascript设计模式
- Javascript MVVM 设计模式 - 如何跟踪脏状态以及谁应该做 Ajaxing
- 包含 2 个或更多对象的页面上的 JavaScript 设计模式
- Django设计模式-在加载时填充客户端JavaScript变量的方法
- Javascript策略设计模式问题
- JavaScript设计模式的建议
- JavaScript设计模式,一个函数正在被覆盖
- 它是什么样的Javascript设计模式/方法
- 了解 JavaScript 中的模块设计模式
- 用于聚合外部数据的 JavaScript 设计模式
- JavaScript 通过参考设计模式传递
- 从文件顶部移动javascript代码,可能使用设计模式
- 如何在 javascript 中为策略设计模式创建属性
- 用于处理成功、失败、重试的异步请求的设计模式?(JavaScript)
- JavaScript 设计模式需要帮助:模块的松散扩充
- 如何实现JavaScript设计模式
- 具有默认值的选项的 JavaScript 设计模式
- JavaScript设计模式
- Javascript Singleton设计模式和闭包
- 设计模式- JavaScript.安全提取深层(可能不存在)对象属性的通用函数