Skip to content

Commit

Permalink
node
Browse files Browse the repository at this point in the history
  • Loading branch information
okbug committed Oct 8, 2021
1 parent 57f4b85 commit 71d909d
Show file tree
Hide file tree
Showing 158 changed files with 6,506 additions and 0 deletions.
Binary file added .DS_Store
Binary file not shown.
Binary file added zf/.DS_Store
Binary file not shown.
Binary file added zf/jiagouke21-2-node/.DS_Store
Binary file not shown.
1 change: 1 addition & 0 deletions zf/jiagouke21-2-node/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules
22 changes: 22 additions & 0 deletions zf/jiagouke21-2-node/1.promise/1.highOrder.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// 高阶函数是什么? 1. 一个函数的参数的参数是一个函数, 我们就可以称之为高阶函数 (回调函数)
// 2. 一个函数返回一个函数 我们也称之为高阶函数 (不单指闭包)

function coreFn(a,b,c){
// 实现了核心逻辑
console.log('core fn',a,b,c)
}
// 如果希望扩展公共的方法, 通过原型链扩展的属性是公共的
Function.prototype.before = function (beforeFn) {
// this => coreFn
return (...args)=>{ // newFn, 箭头函数的特点 没有this 没有arguments , 没有原型链
// 把所有的参数收集成一个数组
beforeFn();
this(...args); // 展开参数
}
}
let newFn = coreFn.before(()=>{
console.log('before fn')
})
// code runner


57 changes: 57 additions & 0 deletions zf/jiagouke21-2-node/1.promise/10.all-finally.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
const fs = require('fs').promises
// Promise.all = function(promises) {
// return new Promise((resolve, reject) => {
// // 将数组中的promise依次执行
// let result = [];
// let index = 0;
// function process(v,k){ // after 实现是一致的
// result[k] = v;
// if(++index == promises.length){ // 解决多个异步并发问题 只能靠计数器
// resolve(result);
// }
// }
// for (let i = 0; i < promises.length; i++) {
// let p = promises[i];
// if (p && typeof p.then === 'function') {
// p.then(data => { // 异步
// process(data,i);
// }, reject); // 如果有一个promise失败了 那么就执行最后的失败逻辑
// }else{
// process(p,i);// 同步的
// }
// }
// })
// }
// // Promise.all 表示全部成功才成功, 如果一个失败了 则失败
// Promise.all([fs.readFile('name.txt', 'utf8'), fs.readFile('age.txt', 'utf8'), 11]).then(data => {
// console.log(data);
// }).catch(err => {
// console.log(err)
// })
// Promise.settled

// 无论成功和失败都会执行的方法 和 try/catch/finally 不一样

Promise.prototype.finally = function (cb) {
return this.then((y)=>{
return Promise.resolve(cb()).then((d)=>y);
},(r)=>{
// cb执行一旦报错 就直接跳过后续的then的逻辑,直接将错误向下传递
return Promise.resolve(cb()).then(()=> {throw r})
})
}
Promise.reject('ok').finally(()=>{ // finally 如果返回的是一个promise那么会有等待效果
console.log('无论成功失败都执行')
return new Promise((resolve,reject)=>{
setTimeout(() => {
resolve('xxxxxxxxxxx'); // 如果是失败 会用这里的失败作为失败的原因
}, 1000);
});
}).then((data)=>{
console.log('成功',data)
}).catch(err=>{
console.log('失败',err)
});


// 事件环 同步异步,async await generator...
48 changes: 48 additions & 0 deletions zf/jiagouke21-2-node/1.promise/2.curring.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// 函数的柯里化 -》 高阶函数

// 柯里化的概念: 如果一个函数有多个参数, 我们可以根据参数的个数 转化成n个函数, 柯里化我们一般都认为参数是一个一个的传递的
// 偏函数: 根据参数的个数 分解成函数,每次调用函数的参数个数可以不是一个

// (如果我们想暂存参数 可以考虑使用柯里化 , 柯里化 就算是一个闭包函数) (更加具体的函数)

// typeof > Array.isArray > Object.prototype.toString.call > instanceof > constructor

function isType(type,val){
return Object.prototype.toString.call(val) === `[object ${type}]`
}
// function isType(type){
// return function (val){
// return Object.prototype.toString.call(val) === `[object ${type}]`
// }
// }
let isString =curring(isType)('String');
let isNumber = curring(isType)('Number')
let isBoolean = curring(isType)('Boolean');


console.log(isString(123));
console.log(isNumber(456));
console.log(isBoolean(123));

// --------------------------------

// 实现一个通用的柯里化函数 开发是经常使用的,面试中经常被问到

function sum(a,b,c,d){
return a+b+c+d;
}
// sum(1,2,3,4)

function curring(fn){
let args = []; // 这里用来记录参数的个数, 记录每次调用传入的总个数
const inner = (arr = []) =>{ // 每次调用的个数
args.push(...arr);
return args.length >= fn.length? fn(...args) : (...args)=> inner(args) // [2,3]
}
return inner();
}
let fn = curring(sum)
let fn1 = fn(1)
let fn2 = fn1(2,3)
let result = fn2(4);
console.log(result);
38 changes: 38 additions & 0 deletions zf/jiagouke21-2-node/1.promise/3.async.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
const fs = require('fs'); // 引入node中的fs模块

// 异步就是不能立即拿到返回值 , 通过回调的方式获取放回结果

// let school = {}
// function finish() {
// if (Reflect.ownKeys(school).length == 2) { // Object.keys()
// console.log(school); // 渲染页面
// }
// }
function after(times, callback) {
let data = {}
return function finish(key, value) { // 函数声明所在的作用域 和执行的作用域不是同一个此时就会产生闭包
data[key] = value;
if (Reflect.ownKeys(data).length == times) {
callback(data);
}
}
}
let finish = after(2, (school) => { // 发布订阅模式 前端最常用的方式
console.log(school);
})
fs.readFile('./name.txt', 'utf8', function(err, data) {
// school['name'] = data;
// finish();
finish('name', data)
})
fs.readFile('./age.txt', 'utf8', function(err, data) {
// school['age'] = data;
// finish();
finish('age', data)
});



// 对于前端 我们希望调用两个ajax 拿到最终的处理结果 去渲染页面 Promise.all

// 1.不用promise 异步就用回调的方式 2.发布订阅模式
44 changes: 44 additions & 0 deletions zf/jiagouke21-2-node/1.promise/4.on-emit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
const fs = require('fs');
// function after(times, callback) {
// let data = {}
// return function finish(key, value) {
// data[key] = value;
// if (Reflect.ownKeys(data).length == times) {
// callback(data);
// }
// }
// }
// let finish = after(2, (school) => {
// console.log(school);
// })

// 发布订阅模式 需要两个 方法 “订阅” “发布” 观察者模式 (观察者模式是基于发布订阅的, 观察者模式是基于类来实现的)

// vue2 响应式原理 发布订阅还是观察者? 视图会依赖数据,数据变化后会“通知”视图更新
let event = {
_arr:[],
data:{},
on(fn){
this._arr.push(fn);
},
emit(key,value){
this.data[key] = value;
this._arr.forEach(fn=>fn(this.data))
}
}
event.on((data)=>{ // 订阅第一次
console.log('收到了一个数据',data)
})
event.on((data)=>{ // 订阅第二次
if(Reflect.ownKeys(data).length == 2){
console.log('收到了全部数据',data)
}
})
fs.readFile('./name.txt', 'utf8', function(err, data) {
event.emit('name', data)
})
fs.readFile('./age.txt', 'utf8', function(err, data) {
event.emit('age', data)
});

// 发布订阅模式是基于一个中间 调度栈,发布和 订阅是解耦的
31 changes: 31 additions & 0 deletions zf/jiagouke21-2-node/1.promise/5.observer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// 观察者模式 需要有两个类 2. 观察者
class Subject{ // 1.被观察者
constructor(name){
this.name = name;
this.observers = [];
this.state = '开心'
}
attach(o){
this.observers.push(o); // 订阅模式, 被观察者需要接受观察者
}
setState(newState){
this.state = newState
this.observers.forEach(o=>o.update(newState))
}
}
class Observer{ // 2. 观察者
constructor(name){
this.name = name;
}
update(state){
console.log(this.name + ':' + '当前状态是' + state);
}
}
// 我家有个小宝宝 , 爸爸和妈妈要关心小宝包的状态 , 小宝宝不开心 会主动通知观察者
let s = new Subject('宝宝');
let o1 = new Observer('爸爸');
let o2 = new Observer('妈妈');
s.attach(o1)
s.attach(o2)
s.setState('不开心');
s.setState('开心');
26 changes: 26 additions & 0 deletions zf/jiagouke21-2-node/1.promise/6.promise.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Promise 基本上不用关心浏览器的兼容性
// 正式课学员 最好能自己手写promise


// Promise是一个类 我们可以new Promise 创造一个实例
// promise 有三个状态 1.默认状态叫等待态 pending 2.resolve表示成功态 fulfilled 3.reject表示变成失败态 rejected

// 只有在pending的状态的时候才能改变状态, 不能从成功变成失败 , 不能从失败变成成功

// 成功有成功的原因 失败同样也有失败的原因 , 除了调用resolve和reject能改变状态外,还可以使用throwerror 抛出异常也会执行到失败的逻辑

let Promise = require('./promise');
let promise = new Promise((resolve, reject) => {
setTimeout(() => {
// throw new Error('error')
reject('ok'); // 让promise变成成功态
resolve('ok')
// return new Error('失败')
}, 1000);
})

promise.then((value) => { // then方法中提供两个参数 1. 成功回调 2.失败的回调
console.log(value, 'success')
}, (reason) => {
console.log(reason, 'fail')
})
44 changes: 44 additions & 0 deletions zf/jiagouke21-2-node/1.promise/7.promise.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// let promise = new Promise((resolve,reject)=>{
// resolve('ok')
// });

// promise.then((data)=>{
// console.log(data)
// },()=>{

// })
let Promise = require('./promise')
const fs = require('fs');
// 为什么要处理链式调用 我们写一个功能 先读取a.txt 文件,拿到具体的内容 读取内容对应的文件
// fs.readFile('./a.txt','utf8',function (err,data) { 回调地狱 错误不好处理,代码全部耦合在一起
// fs.readFile(data,'utf8',function (err,data) {
// console.log(data);
// })
// })

function readFile(...args){
return new Promise((resolve,reject)=>{
fs.readFile(...args,function (err,data) {
if(err) return reject(err);
resolve(data);
})
})
}
// 可以在then方法(成功和失败)中 返回一个promise, promose会采用返回的promise的成功的值或失败原因, 传递到外层下一次then中

// 1. then方法中 成功的回调或者失败的回调返回的是一个promise,那么会采用返回的promise的状态,走外层下一次then中的成功或失败, 同时将promise处理后的结果向下传递
// 2.then方法中 成功的回调或者失败的回调返回的是一个普通值 (不是promise) 这里会将返回的结果传递到下一次then的成功中去
// 3.如果在then方法中 成功的回调或者失败的回调 执行时出错会走到外层下一个then中的失败中去
let promise2 = readFile('./a.txt','utf8').then(data=>{ // 成功 -》 失败
throw new Error('123')
},err=>{
return 200;
})
promise2.then((data)=>{
console.log(data);
},err=>{
console.log('err',err)
})
// promise 一旦成功不能失败
// 如果返回的是一个失败的promoise 、 报错了 。才会走下一个then的失败,否则全部走成功
// 如何实现链式调用? return new Promise() 每次都产生一个全新的promise,来保证状态可以正常的切换
51 changes: 51 additions & 0 deletions zf/jiagouke21-2-node/1.promise/8.promise.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
let Promise1 = require('./promise')

// let promise2 = new Promise1((resolve,reject)=>{
// resolve('ok')
// }).then(data=>{ // 成功 -》 失败
// return new Promise1((resolve,reject)=>{
// setTimeout(() => {
// resolve(new Promise1((resolve,reject)=>{
// setTimeout(() => {
// resolve('ok')
// }, 2000);
// }));
// }, 1000);
// })
// })
// promise2.then((data)=>{
// console.log(data);
// },err=>{
// console.log('err',err)
// })


// 问题1 循环引用的问题
// let promise2 = new Promise((resolve,reject)=>{
// resolve('ok')
// }).then(data=>{ // 成功 -》 失败
// return promise2;// prending resolve()/reject()
// })
// promise2.then((data)=>{
// console.log(data);
// },err=>{
// console.log('err',err)
// })

// 问题2 x.then出错 别人的promise 不知道咋写的,想定义不可枚举的属性 会采用defineProperty,在去取值和设置值的时候做额外逻辑 会采用defineProperty
// Object.defineProperty(x,'then',{
// get(){
// if(times ==2){
// throw new Error()
// }
// }
// })

// 问题3 可选参数
let p = new Promise1((resolve,reject)=>{
reject('ok')
}).then().then().then((data)=>{
console.log(data);
},err=>{
console.log(err,'err')
})
Loading

0 comments on commit 71d909d

Please sign in to comment.