Skip to content

Instantly share code, notes, and snippets.

@tedpan
Last active July 17, 2022 15:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tedpan/9d5dda1d5cbdd98bdbe83c945ddb3d3c to your computer and use it in GitHub Desktop.
Save tedpan/9d5dda1d5cbdd98bdbe83c945ddb3d3c to your computer and use it in GitHub Desktop.
little-utils
// 简易洋葱模型
// app.use(next => {
// console.log(1)
// next()
// })
// app.use(next => {
// console.log(2)
// next()
// })
// app.use(next => {
// console.log(3)
// next()
// })
// app.excute(()=>{
// console.log(4)
// })
// log
// 1
// 2
// 3
// 4
class OnionModel {
constructor() {
this.middlewares = []
}
use(fn) {
this.middlewares.push(fn)
}
async excute(fn) {
const dispatch = this.compose(this.middlewares)
await dispatch(fn)
}
compose(middlewares) {
return function (cb) {
let currentMiddlewareIdx = -1
return dispatch(0)
// 全程用Promise包裹
function dispatch(i) {
if (i <= currentMiddlewareIdx) {
return Promise.reject("next调用太多次!")
}
// cb最后执行
const currentMiddleware = i === middlewares.length ? cb : middlewares[i]
currentMiddlewareIdx = i
if (!currentMiddleware) {
return Promise.resolve()
}
try {
return Promise.resolve(
currentMiddleware(function next() {
return dispatch(i + 1)
})
)
} catch (err) {
return Promise.reject(err)
}
}
}
}
}
const app = new OnionModel()
app.use(next => {
console.log(1)
next()
})
app.use(next => {
console.log(2)
next()
})
app.use(next => {
console.log(3)
next()
})
app.excute(()=>{
console.log(4)
})
interface FormattedRes {
days: number;
hours: number;
minutes: number;
seconds: number;
milliseconds: number;
};
const parseMs = (milliseconds: number): FormattedRes => {
return {
days: Math.floor(milliseconds / 86400000),
hours: Math.floor(milliseconds / 3600000) % 24,
minutes: Math.floor(milliseconds / 60000) % 60,
seconds: Math.floor(milliseconds / 1000) % 60,
milliseconds: Math.floor(milliseconds) % 1000,
};
};
function promisify(fn){
if(typeof fn !== 'function'){
throw new Error('请输入函数!')
}
if (typeof Promise !== "function") {
throw new Error("找不到Promise对象,请实用相关polyfill。");
}
return function(...args){
return new Promise((resolve, reject)=>{
// error first风格
const cb = (err, res)=>{
if(err){
reject(err)
}else{
resolve(res)
}
}
// 原函数需实施并cb,默认最后一个参数是cb
fn.call(this, ...args, cb)
})
}
}
// 根据keyPath,递归更新值,返回深拷贝对象。
function recursiveAssign(obj, keyPath, val){
if(!keyPath.length){
throw new Error('keyPath长度至少为1!')
}
const curKey = keyPath.shift()
const recuriseVal = keyPath.length === 0 ? val : recursiveAssign(obj[curKey], keyPath, val)
return {
...obj,
...{
[curKey]: recuriseVal
}
}
}
@tedpan
Copy link
Author

tedpan commented May 6, 2022

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment