ck koa26700电芯怎么样 多少钱

CK手表型号KOA26700真假?详细资料?价格多少?_百度知道CK的男士手表KOA26761 怎么样?多少钱_百度知道ck手表koa.21561表盘多大_百度知道1003人阅读
NodeJs(4)
Koa中间件方式实现API的Undo功能
API的Undo功能
使用过Gmail或者163邮箱的同学会经常看到,当对邮件进行一些操作时会出现一个类似Toast的提示(大致意思是:操作已经完成,是否撤销)如下图所示:
当点击撤销时,之前执行的操作能够被还原,这种设计对于用户的误操作是一个非常棒的补救方案。
之前听过一句有关交互设计的话说的非常好,不要在用户每做一步操作时弹出Alert让用户选择”确定”或者”取消”,更好的做法是执行操作,然后让用户能够Undo。
实现API Undo的方案
其实Undo是很老的技术,在编辑器中无处不在,只是在API设计中使用的还比较少。最近一直在使用Node开发,因此想使用Node实现一下API的Undo。
首先要明确几点:
并不是所有的API都需要Undo,比如获取数据的接口就完全没有Undo的必要(而且逻辑上也没办法做)
只能针对用户最后一次操作进行Undo
Undo是在用户维度的,用户不能Undo其他用户的操作
传统方案(Plan A):
需要对所有需要Undo的接口提供Undo逻辑;
当用户要Undo最近一次操作时需要调用这个方法(常常会涉及数据库操作)。
新方案(Plan B):
以中间件(类似Java中的拦截器)方式提供Undo服务
对需要Undo的API逻辑放入指定队列延迟执行
调用Undo接口时将最近一次操作从延迟执行的队列中移除
调用其他接口是立即执行延迟队列中的逻辑
可以对任意接口进行undo操作;
逻辑简单,undo时无需操作数据库;
操作真实反映到了数据库;
无需限制undo过期时间;
访问可undo接口后,再访问非undo接口,之前逻辑不能undo;
逻辑较为复杂,undo需要做数据库操作;
并非所有操作都能够undo;
通过上边的方案对比,我发现Plan A更简单、灵活,因此决定实现Plan A。
使用过Koa的通许都知道,koa的中间件非常强大(类似Java web开发中的拦截器),它能够拦截所有请求并执行一些逻辑,例如计算API请求到响应时长等,这里我们就可以使用这个特性将需要Undo的API延迟执行。
首先我们要设置Undo的超时时间,以及那些API需要Undo:
var apis = (options || {}).
var expired = (options || {}).expired || 3000;
还要明确当前访问API的用户:
* `x-identify-key` is used to identify the user of this request,
* one user can not undo another`s request.
var user = context.header['x-identify-key'];
然后延迟执行API逻辑:
var undo = yield delayNext(user, expired, context);
如果用户没有调用Undo接口,则执行逻辑,否则返回’undo’:
if (!undo) { return yield }
this.body = 'undo';
如果用户调用Undo接口,移除延迟执行的逻辑;调用其他接口则立即执行延迟的逻辑:
clearTimeout(undoObj.timeoutId);
if (path === '/undo' && method === 'POST')
else if (undoObj.delayFn)
具体实现逻辑大概就这些,完整代码如下:
* Store users' undo context
var undos = {};
* Expose `undo`
{Object} options Config object for undo
expired: 3000
module.exports = function (options) {
var apis = (options || {}).
var expired = (options || {}).expired || 3000;
return function* (next) {
var context = this;
var path = context.
var needUndo = false;
if (apis && Array.isArray(apis) && apis.length) {
needUndo = apis.filter(function (api) {
return path ===
if (!needUndo && path !== '/undo') { return yield }
var method = context.
* Can not undo get request.
if (method === 'GET') { return yield }
* 'x-identify-key' is used to identify the user of this request,
* one user can not undo another's request.
var user = context.header['x-identify-key'];
if (!user) { return yield }
var undoObj = undos[user];
if (undoObj) {
clearTimeout(undoObj.timeoutId);
if (path === '/undo' && method === 'POST') {
undoObj.delayFn.call(undoObj.context, true);
context.body = 'done';
} else if (undoObj.delayFn) {
undoObj.delayFn.call(undoObj.context, false);
var undo = yield delayNext(user, expired, context);
if (!undo) { return yield }
this.body = 'undo';
* Block the logic for specified ms.
{String} user The user's identity
{String} expired The expired ms
{Object} context The koa context object
function delayNext(user, expired, context) {
return function (callback) {
var delayFn = function (undo) {
delete undos[user];
callback(null, undo);
var timeoutId = setTimeout(delayFn, expired);
undos[user] = {
timeoutId: timeoutId,
delayFn: delayFn,
context: context
目前此项目托管在Github上,,koa-undo具体使用方法项目主页有详细介绍,感兴趣的同学欢迎提Issue、PR;同时koa-undo也发布到了Npm上, ,欢迎大家使用。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:143668次
积分:3608
积分:3608
排名:第6417名
原创:45篇
转载:20篇
译文:37篇
评论:91条
阿里云9折推荐码:ltmk9o
文章:29篇
阅读:45955
(1)(2)(1)(4)(1)(4)(4)(29)(3)(1)(7)(1)(1)(4)(1)(10)(14)(6)(6)(1)}

我要回帖

更多关于 26700 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信