Js
正则
/^(xx)$/
xx 匹配添加首尾,作用是限制全局,相当于用 xx 从头到尾匹配。
[^xyz]
反向与范围一起使用的语法比较反常理,估计是反向会与头符号有冲突,所以这样设计了,会容易带来理解混淆,需要注意。
异步拉平
有这样一个异步流程:
let $ = {
get(url, callback) {
setTimeout(() => {
callback(url.substring(5));
}, 500);
}
};
$.get(url, callback)
thunk法
generator形成回调平行结构,柯里化拆分异步传参,递归控制执行(generator自执行)。
一个像 $.get(url, callback) 这样的异步流程结构,构成部分就是 fn 操作本身,url等外围参数,callback回调函数,可以进行坷里化,分离开外围参数与回调的传递,延迟callback的传递
// fn(arg1, arg2, arg3, ..., callback)
const thunk = function(fn) {
return function (...args) {
return function (callback) {
return fn.call(this, ...args, callback);
}
};
};
// 先接受fn返回坷里化后的流程
let getThunk = thunk($.get);
创造平行结构(同步化),用于描述流程:
// generator 异步逻辑同步化
function* asyncAsSync() {
let result1 = yield getThunk('step/1'); // 传参,
let result2 = yield getThunk(`step/2/${result1}`);
let result3 = yield getThunk(`step/3/${result2}`);
}
自执行的递归结构,第一次执行没有回值,通过递归调用生成器具next来完成执行:
function co(fn) {
var gen = fn();
function nextCallBack(data) {
var result = gen.next(data); // 传参获取完成,result.value 为坷里最后一层,等待传入回调,data为 上一次回调 传入的值,也就是上一次异步执行后承接给下一步的值
if (result.done) return;
result.value(nextCallBack); // 回调传入异步执行,异步执行完会执行传入的当前函数,nextCallBack(breforeCallback(beforeRes)),递归进入下一行,继续上述操作
}
nextCallBack();
}
co(asyncAsSync);
Promise
古老的写法,较难懂,配合 Promise 的结构就好懂很多
因为 Promise 的 resolve,天生提供了 callback,只要将异步结果传递给 resolve 就可以进入 then,也就是下一步操作。之前需要将异步坷里化,现在只需要 传递外围参数,构造 Promise 结构就行了。
function promiseGet(url) {
return new Promise((resolve, _) => {
$.get(url, resolve);
});
}
function * asyncAsSync() {
let result1 = yield promiseGet('step/1');
let result2 = yield promiseGet(`step/2/${result1}`);
let result3 = yield promiseGet(`step/3/${result2}`);
}
function co(fn) {
var g = fn();
function nextCallBack(data){
// result的值为Promise对象
var result = g.next(data);
if (result.done) return result.value;
result.value.then(function(data){
// Promise的then回调中,递归执行nextCallBack(data),传递回调及执行结果
nextCallBack(data);
});
}
co(asyncAsSync)