callback-1.js
// 高阶函数
// 一个函数的参数 是一个函数 (回调)
// 一个函数 返回一个函数 (拆分函数)
// 函数的before
// 希望将核心的逻辑提取出来 ,在外面在增加功能
// 重写原型上的方法
// 不会原型
// js的核心 是回调
Function.prototype.before = function(beforeFn){
return (...args)=>{ // 箭头函数中没有this指向 没有arguments 所以会像上级作用域查找
beforeFn();
this(...args); // 展开运算符 say(1,2,3)
}
}
// AOP 切片 装饰 把核心抽离出来 在核心基础上增加功能
const say = (...args)=>{ // 剩余运算符把所有的参数组成一个数组
console.log('说话',args);
}
const newSay = say.before(()=>{
console.log('您好')
})
const newSay1 = say.before(()=>{
console.log('天气很好')
})
newSay(1,2,3);
newSay1();
// react 事务的改变 可以在前面和后面 同时增加方法
callback-transcation.js
// 事务 开始的时候 做某件事 结束的时候在做某件事
const perform = (anymethod,wrappers)=>{
wrappers.forEach(wrap=>{
wrap.initilizae();
})
anymethod();
wrappers.forEach(wrap=>{
wrap.close();
})
}
perform(()=>{
console.log('说话')
},[
{ // warpper
initilizae(){
console.log('您好')
},
close(){
console.log('再见')
}
},
{ // warpper
initilizae(){
console.log('您好1')
},
close(){
console.log('再见2')
}
}
])
// 柯里化 我们可以把一个大函数拆分成很多的具体的功能
callback-tcurry.js
// 柯里化 : 就是将一个函数拆分成多个函数
// 判断类型 Object.prototype.toString.call
// 高阶函数中包含 柯里化 可以保留参数 bind
const checkType = type => {
return content => {
return Object.prototype.toString.call(content) === `[object ${type}]`;
};
};
// 闭包
let types = ["Number", "String", "Boolean"];
let utils = {};
types.forEach(type => {
utils["is" + type] = checkType(type);
});
console.log(utils.isString("123"));
console.log(utils.isNumber("456"));
// 函数柯里化怎么实现
// 通用的柯里化
// const add = (a, b, c, d, e) => {
// return a + b + c + d + e;
// };
const curring = (fn,arr = [])=>{
let len = fn.length
return (...args)=>{
arr = arr.concat(args); // [1] [1,2,3] < 5
if(arr.length < len){
return curring(fn,arr)
}
return fn(...arr)
}
}
let r = curring(add)(1)(2)(3)(4); // [1,2,3,4,5]
// console.log(r);
const checkType = (type, content) => {
return Object.prototype.toString.call(content) === `[object ${type}]`;
};
let types = ["Number", "String", "Boolean"];
let utils = {};
types.forEach(type => {
utils["is" + type] = curring(checkType)(type); // 先传入一个参数
});
console.log(utils.isString('hello'));
// after 在...之后
callback-after.js
const after = (times, fn) => { // after可以生成新的函数 等待函数执行次数达到我的预期时执行
return ()=>{
if(--times === 0){
fn();
}
}
};
let newAfter = after(3, () => {
console.log("三次后调用");
});
newAfter();
newAfter();
newAfter();
// lodash after
// 并发的问题 发布订阅 观察者模式
callback-all.js
// 1) 我们希望 读取数据 node 异步 会等待同步代码都执行完成后在执行
const fs = require('fs');
let school = {}
// 并发的问题 如何解决 计数器
const after = (times, fn) =>()=> --times === 0 && fn();
let newAfter = after(2, () => {
console.log(school);
});
fs.readFile('name.txt','utf8',(err,data)=>{
school['name'] = data;
newAfter();
});
fs.readFile('age.txt','utf8',(err,data)=>{
school['age'] = data;
newAfter();
});
// 发布订阅模式
callback-on-emit.js
const fs = require('fs');
let school = {}
let e = { // events模块 vue $on $once $off
arr:[],
on(fn){ // [fn1,fn2]
this.arr.push(fn); // redux
},
emit(){
this.arr.forEach(fn => fn());
}
}
e.on(()=>{ // 订阅
console.log('ok')
})
e.on(()=>{ // 订阅
if(Object.keys(school).length === 2){
console.log(school)
}
})
fs.readFile('name.txt','utf8',(err,data)=>{
school['name'] = data;
e.emit(); // 发布
});
fs.readFile('age.txt','utf8',(err,data)=>{
school['age'] = data;
e.emit();
});
// 发布订阅模式 => 观察者模式 (vue watcher)
// 发布订阅模式没有关系的
// 观察者模式 我加小宝宝 心情好
callback-observer.js
class Subject { // 被观察者 小宝宝
constructor(){
this.arr = []; // [o1,o2]
this.state = '我很开心'
}
attach(o){ // 原型上的方法
this.arr.push(o);
}
setState(newState){
this.state = newState;
this.arr.forEach(o=>o.update(newState))
}
}
//观察者模式包含发布订阅
class Observer{ // 观察者 我 我媳妇
constructor(name){
this.name = name
}
update(newState){
console.log(this.name + '小宝宝:'+newState)
}
}
let s = new Subject('小宝宝'); // 小宝宝
let o1 = new Observer('我');
let o2 = new Observer('我媳妇')
s.attach(o1);
s.attach(o2);
s.setState('不开心了');
promise 这个参照了201905jiagouke的promise
// Promise 解决的问题
// 1) 回调嵌套 回调地狱
// 2)错误捕获不好处理错误
// 3)多个异步同步的问题 Promise.all
// 还是基于回调的方式的
// Promise是一个类 默认浏览器 高版本 node 都自带了
// es6-promise
// Promise的概念 规范文档 promise A+ 规范
// Promise 三个状态 等待 成功态 失败态
// 只有等待态 才能变成成功 / 失败
// 如果状态变化后不能在修改状态
promise-1 编码 三个状态,then方法实现,一个value和reason。
const SUCCESS = 'fulfilled'
const FAIL = 'rejected';
const PENDING = 'pending'
class Promise {
constructor(executor) {
this.status = PENDING; // 默认是等待态
this.value= undefined;
this.reason = undefined
let resolve = (value) => {
if(this.status === PENDING){
this.value = value;
this.status = SUCCESS;
}
};
let reject = (reason) => {
if(this.status === PENDING){
this.reason = reason;
this.status = FAIL;
}
};
executor(resolve,reject);
}
then(onFulfilled,onRejected){
if(this.status === SUCCESS){
onFulfilled(this.value);
}
if(this.status === FAIL){
onRejected(this.reason);
}
}
}
module.exports = Promise;
promise-2 promise不是同步的时候数组存放。错误的时候。trycatch.
const SUCCESS = 'fulfilled'
const FAIL = 'rejected';
const PENDING = 'pending'
class Promise {
constructor(executor) {
this.status = PENDING; // 默认是等待态
this.value= undefined;
this.reason = undefined;
this.onResolvedCallbacks = []; // 存储成功的所有的回调 只有pending的时候才存储
this.onRejectedCallbacks = []; // 存储所有失败的
let resolve = (value) => { // 成功
if(this.status === PENDING){
this.value = value;
this.status = SUCCESS;
this.onResolvedCallbacks.forEach(fn=>fn());
}
};
let reject = (reason) => { // 失败
if(this.status === PENDING){
this.reason = reason;
this.status = FAIL;
this.onRejectedCallbacks.forEach(fn=>fn());
}
};
try{
executor(resolve,reject);
}catch(e){
reject(e);
}
}
then(onFulfilled,onRejected){ // 默认看一下状态调用对应的函数
if(this.status === SUCCESS){
onFulfilled(this.value);
}
if(this.status === FAIL){
onRejected(this.reason);
}
if(this.status === PENDING){
this.onResolvedCallbacks.push(()=>{
onFulfilled(this.value);
});
this.onRejectedCallbacks.push(()=>{
onRejected(this.reason);
})
}
}
}
module.exports = Promise;
promise-3 编码 必须返回一个Promise
const PENDING = "PENDING";
const SUCCESS = "FULFILLED";
const FAIL = "REJECTED";
// 返还的那个新的promise x 是then方法中的返回值
function resolvePromise(promise2, x,resolve,reject) { // 考虑的非常全面
if(promise2 === x){
return reject(new TypeError('TypeError: Chaining cycle detected for promise #<Promise>'));
}
// 判断x的类型
}
class Promise {
constructor(executor) {
this.status = PENDING;
this.value = undefined;
this.reason = undefined;
this.onResolvedCallbacks = [];
this.onRejectedCallbacks = [];
const resolve = value => {
if (this.status === PENDING) {
this.value = value;
this.status = SUCCESS;
this.onResolvedCallbacks.forEach(fn => fn());
}
};
const reject = reason => {
if (this.status === PENDING) {
this.reason = reason;
this.status = FAIL;
this.onRejectedCallbacks.forEach(fn => fn());
}
};
try {
executor(resolve, reject);
} catch (e) {
console.log(e);
reject(e);
}
}
// 同一个promise then 多次
then(onFulfilled, onRejected) {
let promise2;
// 可以不停的调用then方法,返还了一个新的promise
// 异步的特点 等待当前主栈代码都执行后才执行
promise2 = new Promise((resolve, reject) => {
if (this.status === SUCCESS) {
setTimeout(() => {
try {
// 调用当前then方法的结果,来判断当前这个promise2 是成功还是失败
let x = onFulfilled(this.value);
// 这里的x是普通值还是promise
// 如果是一个promise呢?
resolvePromise(promise2, x, resolve, reject);
} catch (err) {
console.log(err);
reject(err);
}
});
}
if (this.status === FAIL) {
setTimeout(() => {
try {
let x = onRejected(this.reason);
resolvePromise(promise2, x, resolve, reject);
} catch (err) {
console.log(err);
reject(err);
}
});
}
if (this.status === PENDING) {
this.onResolvedCallbacks.push(()=>{
setTimeout(() => {
try {
let x = onFulfilled(this.value);
resolvePromise(promise2, x, resolve, reject);
} catch (err) {
console.log(err);
reject(err);
}
});
});
this.onRejectedCallbacks.push(()=> {
setTimeout(() => {
try {
let x = onRejected(this.reason);
resolvePromise(promise2, x, resolve, reject);
} catch (err) {
console.log(err);
reject(err);
}
});
});
}
});
return promise2;
}
}
module.exports = Promise;
promise-4 resolvePromise按照promise 加规范实现。
function resolvePromise(promise2, x,resolve,reject) { // 考虑的非常全面
if(promise2 === x){
return reject(new TypeError('TypeError: Chaining cycle detected for promise #<Promise>'));
}
// 判断x的类型
// promise 有n种实现 都符合了这个规范 兼容别人的promise
// 怎么判断 x是不是一个promise 看他有没有then方法
if(typeof x === 'function' || (typeof x === 'object' && x != null)){
try{
let then = x.then; // 去then方法可能会出错
if(typeof then === 'function'){ // 我就认为他是一个promise
then.call(x,y=>{ // 如果promise是成功的就把结果向下传,如果失败的就让下一个人也失败
resolvePromise(promise2,y,resolve,reject); // 递归
},r=>{
reject(r);
}) // 不要使用x.then否则会在次取值
}else{ // {then:()=>{}}
resolve(x);
}
}catch(e){
reject(e);
}
}else{ // x是个? 常量
resolve(x);
}
}
promise-5 当执行过的时候不能再执行,called,值穿透的问题
const PENDING = "PENDING";
const SUCCESS = "FULFILLED";
const FAIL = "REJECTED";
// 严谨 🇬应该判断 别人的promise 如果失败了就不能在调用成功 如果成功了不能在调用失败
function resolvePromise(promise2, x,resolve,reject) {
if(promise2 === x){
return reject(new TypeError('TypeError: Chaining cycle detected for promise #<Promise>'));
}
let called;
if(typeof x === 'function' || (typeof x === 'object' && x != null)){
try{
let then = x.then; // then 可能是getter object.defineProperty
if(typeof then === 'function'){ // {then:null}
then.call(x,y=>{
if(called) return; // 1)
called = true;
resolvePromise(promise2,y,resolve,reject);
},r=>{
if(called) return; // 2)
called = true;
reject(r);
})
}else{
resolve(x);
}
}catch(e){
if(called) return; // 3) 为了辨别这个promise 不能调用多次
called = true;
reject(e);
}
}else{
resolve(x);
}
}
class Promise {
constructor(executor) {
this.status = PENDING;
this.value = undefined;
this.reason = undefined;
this.onResolvedCallbacks = [];
this.onRejectedCallbacks = [];
const resolve = value => {
if (this.status === PENDING) {
this.value = value;
this.status = SUCCESS;
this.onResolvedCallbacks.forEach(fn => fn());
}
};
const reject = reason => {
if (this.status === PENDING) {
this.reason = reason;
this.status = FAIL;
this.onRejectedCallbacks.forEach(fn => fn());
}
};
try {
executor(resolve, reject);
} catch (e) {
reject(e);
}
}
then(onFulfilled, onRejected) { // .catch(function(){}) .then(null,function)
onFulfilled = typeof onFulfilled === 'function'?onFulfilled:val=>val;
onRejected = typeof onRejected === 'function'?onRejected:err=>{throw err}
let promise2;
promise2 = new Promise((resolve, reject) => {
if (this.status === SUCCESS) {
setTimeout(() => {
try {
let x = onFulfilled(this.value);
resolvePromise(promise2, x, resolve, reject);
} catch (err) {
reject(err);
}
});
}
if (this.status === FAIL) {
setTimeout(() => {
try {
let x = onRejected(this.reason);
resolvePromise(promise2, x, resolve, reject);
} catch (err) {
reject(err);
}
});
}
if (this.status === PENDING) {
this.onResolvedCallbacks.push(()=>{
setTimeout(() => {
try {
let x = onFulfilled(this.value);
resolvePromise(promise2, x, resolve, reject);
} catch (err) {
reject(err);
}
});
});
this.onRejectedCallbacks.push(()=> {
setTimeout(() => {
try {
let x = onRejected(this.reason);
resolvePromise(promise2, x, resolve, reject);
} catch (err) {
reject(err);
}
});
});
}
});
return promise2;
}
}
// 希望测试一下这个库是否符合我们的promise A+规范
// promises-aplus-tests
Promise.defer = Promise.deferred = function(){
let dfd = {};
dfd.promise = new Promise((resolve,reject)=>{
dfd.resolve = resolve;
dfd.reject = reject;
});
return dfd;
}
module.exports = Promise;
// npm i promises-aplus-tests -g
// promise 相关方法
// generator
回顾这个是第四天的回顾,放这里来了。
let p = new Promise((resolve,reject)=>{
resolve();
})
// 1).中断promise链 就是返回一个等待的promise
let p1 = p.then(()=>{
console.log('ok');
return new Promise(()=>{})
}).then(()=>{
console.log(1);
})
// 2.finally 实现
Promise.prototype.finally = function(callback){
// callback 直接放到失败里 会导致无法继承上一次的失败
// return this.then(callback,callback);
return this.then((val)=>{
// 等待finally中的函数执行完毕 继续执行 finally函数可能返还一个promise 用Promise.resolve等待返回的promise执行完
return Promise.resolve(callback()).then(()=>val);
//return val; // 如果上一个then是成功就将这个成功向下传递
},(err)=>{
return Promise.resolve(callback()).then(()=>{throw err});
//throw err; // 如果上一个then是失败就将这个失败继续向下抛
})
}
Promise.reject().finally(()=>{
console.log(1);
return new Promise((resovle,reject)=>{
setTimeout(() => {
resovle();
}, 1000);
})
}).catch(e=>{
console.log(e);
})
// 3) race 赛跑 哪个快 用哪个 all是所有完成才完成
let p1 = new Promise((resolve,reject)=>{
setTimeout(() => {
resolve('ok1');
}, 1000);
})
let p2 = new Promise((resolve,reject)=>{
setTimeout(() => {
resolve('ok2');
}, 2000);
})
Promise.race = function(promises){
return new Promise((resolve,reject)=>{
for(let i = 0;i<promises.length;i++){
promises[i].then(resolve,reject); // 只要一个成功就成功
}
})
}
Promise.race([p1,p2]).then(data=>{
console.log(data)
});
// 我有一个网站有一个接口 在两个服务器上
// 4)如何放弃某个promise的执行结果
function wrap(p1){
let fail = null;
let p2 = new Promise((resolve,reject)=>{
fail = reject; // 先将p2失败的方法暴露出来
});
let p = Promise.race([p2,p1]); // race方法返回的也是一个promise
p.abort = fail;
return p
}
let p = wrap(new Promise((resolve,reject)=>{
setTimeout(() => {
resolve('ok');
}, 3000);
}))
p.abort('error');
p.then(data=>{
console.log(data);
}).catch(err=>{
console.log(err);
});
// 5)既能捕获同步有能捕获异步
function fn(){
// 可能函数中抛出了 同步错误 要通过try-catch 捕获异常
// throw new Error('err');
// return new Promise((resolve,reject)=>{
// setTimeout(() => {
// reject('xxx');
// }, 3000);
// })
}
Promise.try = function(callback){
return new Promise((resolve,reject)=>{
// Promise.resolve 只能返回一个成功的promise
return Promise.resolve(callback()).then(resolve,reject);
})
}
Promise.try(fn).then((data)=>{
console.log(data,'---');
},err=>{
console.log('err:'+err);
});
遗漏的一个generator.js
// =================================================================================
// 生成器 生成迭代器的 es6语法
// async + await
// redux-saga
// 返回值叫迭代器
// function * read(){
// yield 1; //产出
// yield 2;
// yield 3
// }
// // iterator 迭代器
// let it = read();
// console.log(it.next()); // {value:1,done:false}
// console.log(it.next());
// console.log(it.next());
// console.log(it.next()); // return unefined
// 将类数组转化成数组
// 类数组的定义 : 1索引 2.长度
// ========================================================================================
function add() {
// ... for of 必须要给当前对象 提供一个生成器方法
console.log([ // ... Array.from
...{
0: 1,
1: 2,
2: 3,
length: 3,
[Symbol.iterator]:function *(){
let index = 0;
while(index !== this.length){
yield this[index++];
}
}
// [Symbol.iterator]() {
// let len = this.length;
// let index = 0;
// // 迭代器 是有next方法 而且方法执行后 需要返回 value,done
// return {
// next: () => {
// return { value: this[index++], done: index === len + 1 };
// }
// };
// }
}
]);
}
add(1, 2, 3, 4, 5);
// ========================================================================================
// function * read(){
// try{
// let a = yield 1;
// console.log(a)
// let b = yield 2;
// console.log(b)
// let c = yield 3;
// console.log(c)
// }catch(e){
// console.log('e:'+e);
// }
// }
// let it = read();
// console.log(it.next('xxx')) // {value:1.done:false} 第一次next参数没有任何意义
// it.throw('xxx')
// ========================================================================================
const fs = require('fs').promises;
function * read(){
let content = yield fs.readFile('./name.txt','utf8'); // age.txt
let age = yield fs.readFile(content,'utf8'); // 10
let xx = yield {age:age + 10}
return xx;
}
// ========================================================================================
function co(it){
return new Promise((resolve,reject)=>{
// 异步迭代需要先提供一个next方法
function next(data){
let {value,done} = it.next(data);
if(!done){
Promise.resolve(value).then(data=>{
next(data);
},err=>{
reject(err);
})
}else{
resolve(value);
}
}
next();
})
}
// ========================================================================================
// 方法1:
// let co = require('co');
co(read()).then(data=>{
console.log(data);
});
// ========================================================================================
// 方法2:
// let it = read();
// it.next().value.then(data=>{
// it.next(data).value.then(data=>{
// let r = it.next(data);
// console.log(r.value);
// })
// })
// ========================================================================================
// async + await
// ========================================================================================
const fs = require('fs').promises;
// async + await 其实是 generator + co的语法糖
async function read(){ // async函数返回的是promise
let r = await Promise.all([p1,p2])
try{
let content = await fs.readFile('./name1.txt','utf8'); // age.txt
let age = await fs.readFile(content,'utf8'); // 10
let xx = await {age:age + 10}
return xx;
}catch(e){
console.log(e);
}
}
read().then(data=>{
console.log(data);
},err=>{
console.log(err);
})
// 作业
// 1) promise.finally
// 2) Promise.try 这个方法 原生里没有
// 3) Promise.race 谁快 用谁
// 4) 如果终止一个promise 不要要当前这个promise结果
// 5) 如果中断promise链
// 练 敲