-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
35db49b
commit 210015a
Showing
12 changed files
with
668 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
node_modules | ||
dist | ||
**/*.swp | ||
.DS_Store |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
## Api Bus | ||
这是一个配合openresty完成的一个工具库,它包含了一个客户端脚本和一个服务端脚本程序。之所以给他命名为Api Bus,是因为它可以合并多个ajax请求到一个请求中,使api们就像是坐上了同一目的地的Bus,一起出发、一起到达。减少了页面连接数,并且得益于openresty的capture_multi子请求的特性,以达到多个请求只取最长响应时间为整体响应时间的特点,大幅提升页面加载速度。 | ||
|
||
## 快速开始 | ||
首先你需要一台安装了openresty的服务器(按照官网安装步骤很简单),将apibus.lua文件拷贝至项目的目录下,配置nginx中apibus的路由地址: | ||
``` | ||
location /apis/apibus { | ||
default_type "application/json; charset=utf-8"; | ||
content_by_lua_file apis/apibus.lua; | ||
} | ||
``` | ||
|
||
在页面中添加jQuery依赖,并引入apibus客户端 | ||
```html | ||
<script src="//cdn.bootcss.com/jquery/1.12.0/jquery.min.js"></script> | ||
<script src="/assets/lib/apibus.js"></script> | ||
``` | ||
|
||
开始使用,将多个ajax请求加入到apibus队列中 | ||
```javascript | ||
apiBus.add([{ | ||
url:'/apis/one', | ||
success: function(result){ | ||
console.log('one api success!') | ||
console.log(result); | ||
}, | ||
complete: function(result){ | ||
console.log('one api complete!') | ||
} | ||
}, { | ||
|
||
url:'/apis/two', | ||
params: {arg: 'params?'}, | ||
success: function(result){ | ||
console.log('two api success!') | ||
console.log(result); | ||
} | ||
} | ||
]); | ||
|
||
apiBus.add({ | ||
url:'/apis/three', | ||
error: function(result){ | ||
console.log('three api error!') | ||
console.log(result); | ||
} | ||
}); | ||
|
||
apiBus.add({ | ||
url:'/apis/four', | ||
method: 'POST', | ||
body: {d: 'ddd?'}, | ||
success: function(result){ | ||
console.log(result.data); | ||
} | ||
}); | ||
|
||
apiBus.start(function(){ | ||
console.log('api bus done!'); | ||
}); | ||
``` | ||
|
||
# License | ||
|
||
MIT |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
-- Api Bus for contact ajax requests | ||
-- | ||
-- Author: Michael LYU <[email protected]> | ||
-- | ||
-- Date: 2016-01-23 | ||
-- | ||
-- Version: 1.0.0 | ||
|
||
local cjson = require "cjson.safe"; | ||
|
||
ngx.req.read_body(); | ||
local post_args = ngx.req.get_post_args(); | ||
local bus = cjson.decode(post_args.apibus); | ||
|
||
local methods = { | ||
GET = ngx.HTTP_GET, | ||
POST = ngx.HTTP_POST, | ||
PUT = ngx.HTTP_PUT, | ||
DELETE = ngx.HTTP_DELETE | ||
}; | ||
|
||
local seats = {}; | ||
local seat; | ||
local options; | ||
for k, v in pairs(bus) do | ||
seat = {v.url}; | ||
options = {}; | ||
|
||
if v.method then | ||
options['method'] = methods[string.upper(v.method)]; | ||
end | ||
if v.params then | ||
options['args'] = v.params; | ||
end | ||
if v.body then | ||
options['body'] = v.body; | ||
end | ||
|
||
if table.getn(options) then | ||
table.insert(seat, 2, options); | ||
end | ||
|
||
table.insert(seats, k, seat); | ||
end | ||
|
||
local responses = {ngx.location.capture_multi(seats)}; | ||
|
||
local bus = {}; | ||
local res; | ||
for k, v in pairs(responses) do | ||
if v.status == 200 then | ||
res = cjson.decode(v.body); | ||
else | ||
res = "error"; | ||
end | ||
|
||
table.insert(bus, k, res); | ||
end | ||
|
||
ngx.say(cjson.encode(bus)); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
local cjson = require "cjson.safe"; | ||
|
||
ngx.req.read_body(); | ||
local post_args = ngx.req.get_post_args(); | ||
local bus = cjson.decode(post_args.apibus); | ||
|
||
local methods = { | ||
GET = ngx.HTTP_GET, | ||
POST = ngx.HTTP_POST, | ||
PUT = ngx.HTTP_PUT, | ||
DELETE = ngx.HTTP_DELETE | ||
}; | ||
|
||
local seats = {}; | ||
local seat; | ||
local options; | ||
for k, v in pairs(bus) do | ||
seat = {v.url}; | ||
options = {}; | ||
|
||
if v.method then | ||
options['method'] = methods[string.upper(v.method)]; | ||
end | ||
if v.params then | ||
options['args'] = v.params; | ||
end | ||
if v.body then | ||
options['body'] = v.body; | ||
end | ||
|
||
if table.getn(options) then | ||
table.insert(seat, 2, options); | ||
end | ||
|
||
table.insert(seats, k, seat); | ||
end | ||
|
||
local responses = {ngx.location.capture_multi(seats)}; | ||
|
||
local bus = {}; | ||
local res; | ||
for k, v in pairs(responses) do | ||
if v.status == 200 then | ||
res = cjson.decode(v.body); | ||
else | ||
res = "error"; | ||
end | ||
|
||
table.insert(bus, k, res); | ||
end | ||
|
||
ngx.say(cjson.encode(bus)); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
worker_processes 1; | ||
error_log logs/error.log; | ||
events { | ||
worker_connections 1024; | ||
} | ||
http { | ||
server { | ||
listen 8080; | ||
lua_code_cache off; | ||
root ./public; | ||
location /apis/apibus { | ||
default_type "application/json; charset=utf-8"; | ||
content_by_lua_file apis/apibus.lua; | ||
} | ||
location /apis/one { | ||
default_type application/json; | ||
content_by_lua ' | ||
local cjson = require "cjson.safe"; | ||
ngx.say(cjson.encode({status = 1, data = {1, 2, 3}})); | ||
'; | ||
} | ||
location /apis/two { | ||
default_type application/json; | ||
content_by_lua ' | ||
local cjson = require "cjson.safe"; | ||
ngx.say(cjson.encode({status = 1, data = ngx.var.arg_arg})); | ||
'; | ||
} | ||
location /apis/three { | ||
default_type application/json; | ||
content_by_lua ' | ||
throw error; | ||
'; | ||
} | ||
location /apis/four { | ||
default_type application/json; | ||
content_by_lua ' | ||
local cjson = require "cjson.safe"; | ||
ngx.req.read_body(); | ||
local post_args = ngx.req.get_post_args(); | ||
ngx.say(cjson.encode({status = 1, data = post_args})); | ||
'; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
/*! | ||
* Api Bus for contact ajax requests | ||
* | ||
* Author: Michael LYU <[email protected]> | ||
* | ||
* Date: 2016-01-23 | ||
* | ||
* Version: 1.0.0 | ||
*/ | ||
(function(factory) { | ||
'use strict'; | ||
if (typeof define === 'function' && define.amd) { | ||
define(['jquery'], function($) { | ||
return factory($); | ||
}); | ||
} else if (typeof exports !== 'undefined') { | ||
module.exports = factory(require('jquery')); | ||
} else { | ||
factory(jQuery); | ||
} | ||
})(function($, undefined) { | ||
'use strict'; | ||
|
||
var isUndefined = function (value) {return typeof value === 'undefined';} | ||
var isObject = function (value){return value !== null && typeof value === 'object';}; | ||
var isFunction = function isFunction(value) {return typeof value === 'function';}; | ||
var isString = function isString(value) {return typeof value === 'string';} | ||
var isArray = Array.isArray; | ||
|
||
var getSeats = function (){ | ||
var seats = []; | ||
for(var i = 0, len = bus.length; i < len; i++){ | ||
seats[i] = {url: bus[i].url}; | ||
isString(bus[i].method) && (seats[i].method = bus[i].method); | ||
isString(bus[i].params) && (seats[i].url + (bus[i].url.indexOf('?') === -1 ? '?' : '&') + bus[i].params); | ||
isObject(bus[i].params) && (seats[i].params = bus[i].params); | ||
isString(bus[i].body) && (seats[i].body = bus[i].body); | ||
isObject(bus[i].body) && (seats[i].body = $.param(bus[i].body)); | ||
} | ||
return seats; | ||
}; | ||
|
||
var bus = [], | ||
seat, | ||
xhr; | ||
|
||
var config = { | ||
way: '/apis/apibus', | ||
name: 'apibus', | ||
autoClear: true | ||
}; | ||
|
||
var apiBus = function(seats){ | ||
if(isUndefined(seats)){ | ||
return; | ||
} | ||
|
||
isArray(seats) || (seats = [seats]); | ||
|
||
for(var i = 0, len = seats.length; i < len; i++){ | ||
if(isObject(seats[i]) && isString(seats[i].url)){ | ||
seat = {}; | ||
|
||
seat.url = seats[i].url; | ||
isString(seats[i].method) && (seat.method = seats[i].method); | ||
(isObject(seats[i].params) || isString(seats[i].params)) && (seat.params = isString(seats[i].params) ? seats[i].params : seats[i].params); | ||
isObject(seats[i].body) && (seat.body = seats[i].body); | ||
isFunction(seats[i].success) && (seat.success = seats[i].success); | ||
isFunction(seats[i].error) && (seat.error = seats[i].error); | ||
isFunction(seats[i].complete) && (seat.complete = seats[i].complete); | ||
|
||
bus.push(seat); | ||
} | ||
} | ||
}; | ||
|
||
apiBus.config = function(options){ | ||
if(isUndefined(options)){ | ||
return config; | ||
} | ||
|
||
$.extend(config, options); | ||
}; | ||
|
||
apiBus.add = function(seats){ | ||
apiBus(seats); | ||
}; | ||
|
||
apiBus.start = function(callback){ | ||
if(bus.length === 0){ | ||
return; | ||
} | ||
|
||
var data = {}; | ||
data[config.name] = JSON.stringify(getSeats()); | ||
xhr = $.post(config.way + (config.way.indexOf('?') === -1 ? '?' : '&') + '&bust=' + new Date().getTime(), data) | ||
.success(function(result){ | ||
if(isArray(result)){ | ||
for(var i = 0, len = bus.length; i < len; i++){ | ||
if(isString(result[i]) && result[i] === 'error' && isFunction(bus[i].error)){ | ||
bus[i].error(result[i]); | ||
} | ||
else if(isFunction(bus[i].success)){ | ||
bus[i].success(result[i]); | ||
} | ||
} | ||
} | ||
}) | ||
.error(function(){ | ||
for(var i = 0, len = bus.length; i < len; i++){ | ||
if(isFunction(bus[i].error)){ | ||
bus[i].error.apply(this, arguments); | ||
} | ||
} | ||
}) | ||
.complete(function(result){ | ||
for(var i = bus.length - 1; i >= 0; i--){ | ||
if(isFunction(bus[i].complete)){ | ||
bus[i].complete(result[i]); | ||
} | ||
} | ||
|
||
if(config.autoClear){ | ||
apiBus.clear(); | ||
} | ||
|
||
if(isFunction(callback)){ | ||
callback(); | ||
} | ||
}); | ||
}; | ||
|
||
apiBus.stop = function(){ | ||
if(xhr){ | ||
xhr.abort(); | ||
} | ||
}; | ||
|
||
apiBus.clear = function(){ | ||
bus.length = 0; | ||
}; | ||
|
||
window.apiBus = $.apiBus = apiBus; | ||
}); |
Oops, something went wrong.