Last active
April 13, 2018 06:42
-
-
Save xialvjun/78b0411f5f446bc930866cd3f6997757 to your computer and use it in GitHub Desktop.
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
// 返回一个可以任意执行,但内部并发只有 count 的函数 | |
function limit(fn, count) { | |
let n = 0; | |
let ps = []; | |
function work(...args) { | |
n++; | |
let rp = fn(...args); | |
rp.then(_ => { | |
n--; | |
let next = ps.shift();// ps[0]; | |
if (next) { | |
// ps = ps.slice(1); | |
next.resolve(true); | |
} | |
}).catch(e => { | |
n--; | |
let next = ps.shift(); | |
if (next) { | |
next.resolve(true); | |
} | |
throw e; | |
}); | |
return rp; | |
} | |
return function(...args) { | |
fn = fn.bind(this); | |
if (n === count) { | |
return (new Promise((resolve, reject) => { | |
ps.push({resolve, reject}); | |
})).then(_ => work(...args)); | |
} | |
return work(...args); | |
} | |
} | |
export function parallel_limit(fn, count=1) { | |
const ps = []; | |
let working = 0; | |
return function(...args) { | |
// 把返回的箭头函数改为普通函数,并且修改 fn 的 this,从而让包装后的函数能被外界操纵 this... | |
// 当然,如果传进来的 fn 已经是一个 bind this 之后的函数,那就无影响... | |
// 整体上就是尊重外界传递的 fn 的绑定状态...适合于 @xialvjun/create-react-context 库 | |
fn = fn.bind(this); | |
return new Promise((resolve, reject) => { | |
ps.push({ resolve, reject, args }); | |
work(); | |
}); | |
}; | |
function work() { | |
if (working >= count) { | |
return; | |
} | |
const next = ps.shift(); | |
if (next) { | |
working++; | |
fn(...(next.args)) | |
.then(_ => { | |
working--; | |
work(); | |
next.resolve(_); | |
}) | |
.catch(e => { | |
working--; | |
work(); | |
next.reject(e); | |
}); | |
} | |
} | |
} | |
export function args_parallel_limit(fn, count=1) { | |
const args_fns = []; | |
return function(...args) { | |
fn = fn.bind(this); | |
let args_fn = args_fns.find(args_fn => args_fn[0].length === args.length && args_fn[0].every((arg, i) => arg = args[i])); | |
if (args_fn) { | |
return args_fn[1](...args); | |
} | |
args_fn = [args, parallel_limit(fn, count)]; | |
args_fns.push(args_fn); | |
return args_fn[1](...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
((function(doc, win) { | |
var docEle = doc.documentElement, | |
evt = "onorientationchange" in window ? "orientationchange" : "resize", | |
fn = function() { | |
// 414 是设计稿 iPhone 6 Plus 的宽度。。。实际需要的时候,需要把 414 换成真实设计稿的宽度 | |
// docEle.style.fontSize = (100 / 414) + "vw"; | |
var width = docEle.clientWidth; | |
// 本来 docEle.style.fontSize 只需要 = width/414 就好, width/414 值会很小,而浏览器有最小字体限制,导致该项无用,所以乘以 100 | |
width && (docEle.style.fontSize = (100 * width / 414) + "px"); | |
// 于是以后的所有的长度,都直接使用设计稿里的长度的数字,但是把单位换成 rem,并除以 100。。。不用程序员去换算百分比 | |
}; | |
win.addEventListener(evt, fn, false); | |
doc.addEventListener("DOMContentLoaded", fn, false); | |
})(document, window)); |
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
* { | |
margin: 0; | |
padding: 0; | |
box-sizing: border-box; | |
} | |
*::-webkit-scrollbar { | |
/* | |
这里不用担心,scrollbar 的宽度不会占用百分比。。。 | |
但是从有 scrollbar 变为无 scrollbar,内容的宽度仍然会发生改变,可能把 scrollbar 变成游离元素会更好 | |
*/ | |
width: 5px; | |
} | |
*::-webkit-scrollbar-track { | |
-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3); | |
} | |
*::-webkit-scrollbar-thumb { | |
background-color: darkgrey; | |
outline: 1px solid slategrey; | |
} | |
/* | |
其实要实现跟 mac 原生滚动条一模一样,有三个难点: | |
1. 样式。。。但这个已经没有了,因为能设置样式了 | |
2. 滚动条不占位置。。。这个我没解决,我想把他脱离文档流,但发现做不到,想设置 margin-left 负数,也没用 | |
3. 滚动条在滚动时显示,不滚动时隐藏。。。这个需要 js。。。但是换种 hover 时半透明显示,不 hover 时完全隐藏,这种效果也不错。。。 | |
所以只有 2 最难实现。 | |
另外,还尝试过把 width 设置为 0,但是也给它设置一个 outset 的 box-shadow,但是也没有显示出来,哪怕加了 overflow: visiable 也不行。。。 | |
另外有个这个思路 http://www.zhangxinxu.com/wordpress/2015/01/css-page-scrollbar-toggle-center-no-jumping/ | |
另外也可以试试 js 的 scroller。。。例如 github.com/forcedotcom/scrollerjs or cubiq/iscroll 前者的 demo 更好,后者的文档更好 | |
*/ |
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
// 这个函数把定义任务与执行任务区分开。。。而且还会缓存任务结果,以及任务如果上次失败,则下次执行将会重新执行。。。 | |
// 从而可以轻松构建全局可能会失败多次,但只会执行成功一次,的全局唯一懒执行任务 | |
// 这个函数在理解时要注意不同的参数会返回不同的函数。。。也就是说需要预定义参数。。。memonize 不需要预定义参数 | |
function task(fn) { | |
return function(...args) { | |
fn = fn.bind(this); | |
// 直接 Promise.reject 后面没直接接 catch 就会报错 | |
// let p = Promise.reject(false); | |
let p; | |
// 增加强制刷新功能。。。 | |
return (refresh) => { | |
if (refresh) { | |
p = fn(...args); | |
return p; | |
} | |
return (p || Promise.reject(false)).catch(e => { | |
p = fn(...args); | |
return p; | |
}) | |
}; | |
} | |
} | |
function better_task(fn) { | |
return function(...args) { | |
fn = fn.bind(this); | |
let p = null; | |
return refresh => ((refresh || !p) ? Promise.reject(false) : p).catch(e => { | |
p = fn(...args); | |
return p; | |
}); | |
} | |
} | |
// ! task 得到的第一次的 promise 与 第二次的 promise 是不一样的。。。如果第一次的 promise throw 了,则第二次的是一个全新的 promise | |
// ! 事实上每次都是一个全新的 promise,因为 catch 就是生成一个新的 promise 对象 | |
// ! 还应有一种只要两次请求是连在一起的,则保证返回同一个 promise 。。。这两种应该区分开。。。 | |
// ! 也就是说第一种只缓存正确的 promise,第二种则仅仅是缓存 promise 无论对错 | |
function cache_pending_promise(fn) { | |
let p = null; | |
return function(...args) { | |
fn = fn.bind(this); | |
if (!!p) { | |
return p; | |
} | |
p = fn(...args).then(a => { | |
p = null; | |
return a; | |
}).catch(e => { | |
p = null; | |
throw e; | |
}); | |
return p; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment