- 37
- 0
在开发过程中,可能会遇到用户连续操作,而造成请求重复的问题(比如用户添加工作经验列表时WorkExperienceAdd可能重复添加),这个时候只需要一次请求即可,考虑到引入了rxjs想结合switchMap来实现,但是又不能影响到其他的请求(请求用户的工作经验列表WorkExperienceList),所以想请求一下帮助,有什么比较好的实现?
1、websocket服务部分
angular.module("app").factory("wsService", ["$q", "$ionicLoading", "i18n", "timeService", "commonService", "CONFIG",
function ($q, $ionicLoading, i18n, timeService, commonService, CONFIG) {
"use strict";
const url = CONFIG.url.server;
let ws = new WebSocket(url),
arr = [],
log = [],
subject = new Rx.Subject();
function reConnect(url) {
let ws = new WebSocket(url);
return bridgeWs(ws);
}
function send(data) {
if (data) {
sendData(data);
} else {
_.each(arr, item => {
sendData(item);
});
arr = [];
}
function sendData(data) {
if (data.parameters.showLoading) data.parameters = _.omit(data.parameters, ["showLoading"]);
ws.send(JSON.stringify(data));
}
}
function createRecord(msg, type) {
const message = msg + " " + timeService.getTime() + " " + type.toUpperCase();
log.push(message);
}
function message(event) {
let data = JSON.parse(event.data);
const criticalCode = 2000;
data.isError = data.code > criticalCode;
subject.next(data);
}
function close(event) {
createRecord(event.reason, "close");
}
function error() {
commonService.showShortCenter(i18n.server_error_tip);
createRecord("connection error ", "error");
console.error(log.join("\\n"));
}
function open() {
!_.isEmpty(arr) && send();
createRecord("connection established ", "open");
}
function bridgeWs(ws) {
ws.onmessage = message;
ws.onclose = close;
ws.onerror = error;
ws.onopen = open;
return ws;
}
bridgeWs(ws);
return {
record: log,
get: function (data) {
console.log("get中的data");
console.log(data);
const readyState = 0,
errorState = 2,
closeState = 3;
if (ws.readyState === readyState) {
arr.push(data);
} else if (_.includes([errorState, closeState], ws.readyState)) {
ws.close();
arr = [];
arr.push(data);
//TODO 重连直至连上为止
ws = reConnect(url);
} else {
data.parameters.showLoading && commonService.showLoading();
send(data);
return new Date().getTime();
}
},
close: ws.close,
status: function () {
return ws.readyState;
},
subject: subject
};
}]);
2、api服务部分
angular.module("app").factory("apiService", ["API", "i18n", "wsService", "$state", "commonService",
function (API, i18n, wsService, $state, commonService) {
"use strict";
const subject = new Rx.Subject(),
redirectCode = 2101;
let parts = wsService.subject.partition(data => data.code === redirectCode);
parts[0].subscribe(() => {
$state.go("login");
});
parts[1].subscribe(data => {
subject.next(data);
});
function createErrorSheet(item, record = {}) {
if (_.isArray(item)) return _.map(item, commonService.curry2Right(_.assign)(record));
return _.map(_.toPairs(item), ele => {
let key = _.isArray(ele[1]) ? "key" : "form";
record[key] = ele[0];
return createErrorSheet(ele[1], record);
});
}
function arrangeErrorInfo(data) {
if (_.isString(data)) return data;
return _.chain(data).map(item => createErrorSheet(item)).flattenDeep().value();
}
function curry2(fn) {
return f => s => fn.call(fn, f, s);
}
class Command {
constructor(path, parameters) {
this.command = {path};
this.parameters = parameters;
}
}
const get = curry2((path, params) => {
const option = new Command(path, params);
console.log("get中的option");
console.log(option);
wsService.get(option);
});
class SubApi extends API {
constructor() {
super();
this.subject = subject;
}
getLogin(param) {
get(this.login)(param);
}
getWorkExperienceList(param) {
get(this.workExperienceList)(param);
}
getWorkExperienceAdd(param) {
get(this.workExperienceAdd)(param);
}
handleError(data) {
commonService.hideLoading();
const message = arrangeErrorInfo(data.detail),
tip = _.isString(message) ? _.find([message, `1、${data.msg}`], _.identity) :
_.map(message, (msg, index) => `${index + 1}、${msg.message}\n`).join("");
try {
window.plugins.toast.showLongCenter(tip);
} catch (e) {
commonService.alert(i18n.api_error_tip, tip);
}
}
isDataOf(path, data) {
return path === data.command.path;
}
isDataFor(data, ...path) {
return _.includes(path, data.command.path);
}
predicatePath(path) {
return data => path === data.command.path;
}
}
return new SubApi();
}]);
3、页面逻辑(用户可以操作增加工作经验列表)
angular.module("app").controller("personalCtrl", ["$scope", "apiService", "$state", "commonService", "ionicDatePicker",
"$ionicPopover", "timeService", "$stateParams", "CONFIG", "$cordovaStatusbar", "validateService",
function ($scope, apiService, $state, commonService, ionicDatePicker, $ionicPopover, timeService, $stateParams, CONFIG, $cordovaStatusbar, validateService) {
"use strict";
const i18n = $scope.i18n,
current = $stateParams.subState;
let isDateSelecting = false;
function selectDate(ele) {
if (isDateSelecting) return;
const self = this; //don't fix, use automatic this;
isDateSelecting = true;
ionicDatePicker.openDatePicker({
callback(val) {
_.isString(ele) && (self.data[ele] = timeService.getDateInfo(val).fullDate);
_.isObject(ele) && (ele.value = timeService.getDateInfo(val).fullDate);
isDateSelecting = false;
},
cancel() {
isDateSelecting = false;
}
});
}
const subject = new Rx.Subject(),
apiServiceSubscription = apiService.subject.subscribe(data => {
if (data.isError) {
apiService.handleError(data);
} else {
subject.next(data);
}
});
subject.filter(data => apiService.isDataOf(apiService.workExperienceList, data)).subscribe(() => {
$scope[current].dealData(data.data);
});
subject.filter(data => apiService.isDataOf(apiService.workExperienceAdd, data)).subscribe(() => {
$scope.editable = false;
$scope.popover && $scope.popover.isShown() && $scope.popover.hide();
$scope[current].queryData();
$scope[current].clearCardInfo && $scope[current].clearCardInfo();
$scope.$digest();
});
$scope.work = {
title: "工作经验",
platformData: {
data: null,
isShow: true
},
addData: {
data: null,
isShow: false
},
queryData() {
const option = {
sid: $scope.userInfo.sid,
self: 1
};
apiService.getWorkExperienceList(option); **// 查询工作经验**
},
addExperience() {
const option = this.getOption();
if (this.validateUserInput(option)) {
apiService.getWorkExperienceAdd({ **// 增加工作经验**
sid: $scope.userInfo.sid,
work_exper_form: option
});
}
},
validateUserInput() {
return _.every(this.cardInfo, card => card.validateFn(card));
},
getOption() {
return _.reduce(this.cardInfo, (accumlator, card) => {
accumlator[card.key] = card.value;
return accumlator;
}, {});
},
init() {
$state.go("home.personal.work");
$scope.showAdd = true;
this.queryData();
}
};
$scope[current].init();
$scope.$on("$ionicView.beforeLeave", () => {
apiServiceSubscription.unsubscribe();
});
}]);
1
打赏
收藏
点击回答
您的回答被采纳后将获得:提问者悬赏的 10 元积分
网站公告
- 扫一扫访问手机版
回答动态

- 神奇的四哥:发布了悬赏问题阿里云幻兽帕鲁服务器更新之后。服务器里面有部分玩家要重新创建角色是怎么回事啊?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题函数计算不同地域的是不能用内网吧?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题ARMS可以创建多个应用嘛?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题在ARMS如何申请加入公测呀?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题前端小程序接入这个arms具体是如何接入监控的,这个init方法在哪里进行添加?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题阿里云幻兽帕鲁服务器刚到期,是不是就不能再导出存档了呢?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题阿里云幻兽帕鲁服务器的游戏版本不兼容 尝试更新怎么解决?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题阿里云幻兽帕鲁服务器服务器升级以后 就链接不上了,怎么办?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题阿里云幻兽帕鲁服务器转移以后服务器进不去了,怎么解决?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题阿里云幻兽帕鲁服务器修改参数后游戏进入不了,是什么情况?预计能赚取 0积分收益
- 回到顶部
- 回到顶部
