1. 高阶函数
// 高阶函数: 如果一个函数的参数是一个函数(回调函数也是高阶函数的一种)
// 如果一个函数返回 一个函数 当前函数也是一个 高阶函数
// 扩展当前业务代码
function say(a,b){
console.log("say",a,b);
}
// 给某个方法添加方法 在执行之前调用
Function.prototype.before = function(callback){
// let _this = this; // 让this 指向say
//return function(){
// callback();
// 注意 this
// this()
//}
// 剩余运算符 ...args ... 在函数参数里 把所有参数组成数组 在函数调用 表示展开 参数依次传入
return (...args)=>{
// 箭头函数 没有this 和 arguments
callback();
this(...args);
}
}
let beforeSay = say.before(function(){
console.log('before.say');
});
// 之后调用 beforeSay
beforeSay("hello","word");
2. 函数柯里化
// 函数柯里化 函数反柯里化
// 判断变量的类型
// 常用的判断 类型的方法。
- typeof 不能判断对象类型 ( 数组和 对象都是 Object );
- constructor 判断类型的构造
- instanceof 判断谁是谁 实例 (判断会存在不准确的情况) __proto__ ;
- Object.prototype.toString.call() // 获取对象原型上的 toStiong 上的 this 是当前的对象 缺陷 不能判断谁是谁的实例
function istype(value,type){
return Object.prototype.toString.call(value) === `[object ${type}]`;
};
// 方法的详细拆分 isType => isString isArray
console.log(istype([],'Array'));
// 柯里化
function isType(type){
return function(value){
return Object.protottpe.toString.call(value) === `[Object ${type}]`
}
}
let isString = isType('String'); // 创造固定类型函数
let isArray = isType('Array');
let Object = isType('Object');
console.log(isString('value'));
console.log([]);
// 实现通用函数柯里化 (通过一个通用的柯里化函数,实现函数的柯里化)
const currying = (fn,arr=[])=>{
let len = fn.length; // 获取函数参数的个数
return (...args)=>{
let arg = arr.concat(args); // [...arr,...args]
if(arg.length < len){
return currying(fn,arg);
}
return fn(...arg);
}
}
const add = (a,b,c,d,e)=>{
return a + b + c + d + e;
}
let r = currying(add)(1)(2,3)(4,5);
isArray = curring(istype)('Array');
isString = curring(istype)('String');
console.log(isArray([]));
console.log(isString('hello'));
// 多个异步请求 同时获取 最终结果
const after = (times, callback) => () => {
if (--times === 0) {
callback();
}
};
const newFn = after(3, () => {
console.log("ok");
});
// on-emit 模式
let man = {}
let fs = require('fs'); // file system
let even = { // 发布和订阅没有明星的关系
arr:[],
on(fn){
this.arr.push(fn);
},
emit(){
this.arr.forEach(fn=>fn());
},
};
even.on(()=>{console.log("读取数据")})
fs.readFile('./name.txt','utf8',(err,data)=>{
man.name = data;
// console.log(man,'1')
even.emit();
})
fs.readFile('./age.txt','utf8',(err,data)=>{
man.age = data;
// console.log(man,"3")
even.emit();
})
even.on(()=>{
if(Object.keys(man).length !==2)return
console.log("读取数据",man)
})
// 观察者模式 观察者 和被观察者 观察者需要发到被观察者中 被观察者发生变化 需要告之被观察者
// 内部也是基于订阅发布者模式 收集观察者 状态变化 通知观察者
class Subject { // 被观察者
constructor(name) {
this.name = name;
this.state = "面无表情";
this.observers = [];
}
attach(o){
this.observers.push(o);
}
SetState(newState){
this.state = newState;
this.observers.forEach(o=>o.update(this))
}
}
class Observer{
constructor(name) {
this.name = name;
}
update(baby){
console.log(`这个${this.name}被通知了${baby.name}他${baby.state}`);
}
}
let baby = new Subject('张太阳');
let parent = new Observer('爸爸');
let mother = new Observer('妈妈');
baby.attach(parent);
baby.attach(mother);
baby.SetState('饿哭了');
promise 的简单理解
// promise 的概念 以及特点
// https://promisesaplus.com/ promisea+ 规范
// https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise
// promise Es6 内部已经完全实现 ie 不支持promis , 需要 polyfill es6-promise
// promise 的产生原因 用于解决异步问题
// 1. 异步 请求的多并发问题 (希望同步最终结果) promise.all
// 2. 异步请求问题(异步回调儿地狱-回调金字塔问题)上一个请求的输出是下一个请求的参数 Promise 的链式调用 可以解决这个问题
// 3. 缺陷 还是基于回调的
// promise 有三个状态: 成功态(resolve) 失败态(reject) 等待态(pending) (不成功也不失败)
// promise 就是一个类
// 用户自己决定失败的原因和成功的原因 成功和失败也是用户自己定义的 取决于用户调了那个方法
// 1.promise 执行器是默认立即 执行
// 2.promise 的每个实例都有一个 then 的方法 一个参数是成功的回调 一个参数是失败的回调
// 3.如果执行函数的时候发生了异常(执行了异常的逻辑) 也会执行失败
// 4.promise 一旦成功就不可能失败 一旦失败就不可能成功
let promise = new Promise((resolve,reject)=>{
// throw new Error("失败了");
console.log(1)
reject("没有发工资");
resolve("今天墨鱼了");
})
console.log(2);
console.log(promise);
promise.then((resole)=>{
// 这里走的是成功的回调函数
console.log( "success",resole);
},(reject)=>{
// 这里走的是失败的回调函数
console.log("err",reject);
})
实现一个简单的promise
// promise 有三个状态 pending(等待态) resolve(成功态) reject(失败态)
let PENDING = "PENDING"; // 等待态
let RESOLVE = "RESOLVE"; // 成功态
let REJECT = "REJECT"; // 失败态
// promise 是个类 创建一个promise 类
class Promise{
constructor(executor){
this.status = PENDING;
this.value = undefined; // 成功的原因
this.reason = undefined; // 失败的原因
let resolve = (value)=>{
if(this.status === "PEDING"){
this.value = value;
this.status = RESOLVE;
}
} // 不属于实例上的 是单独每个人都有的
let reject = (reason)=>{
if(this.status === "PENDING"){
this.reason = reason;
this.status = REJECT;
}
}
// promise 发生了错误的逻辑也会 执行 失败
try{
executor(resolve,reject); // 这个是执行器 默认立即执行
}catch (e) {
console.log(e)
reject(e);
}
}
then(onFulfiled,onRjected){
if(this.status === RESOLVE){
onFulfiled(this.value);
}
if(this.status === REJECT){
onRjected(this.reason);
}
}
}
promise 的 then 方法 实现
// promise 有三个状态 pending(等待态) resolve(成功态) reject(失败态)
let PENDING = "PENDING"; // 等待态
let RESOLVE = "RESOLVE"; // 成功态
let REJECT = "REJECT"; // 失败态
// promise 是个类 创建一个promise 类
class Promise{
constructor(executor){
this.status = PENDING;
this.value = undefined; // 成功的原因
this.reason = undefined; // 失败的原因
this.onResolvedCallbacks = []; // 成功的回调函数 集合
this.onRejectedCallbacks =[]; // 失败的回调函数 集合
let resolve = (value)=>{
if(this.status === "PEDING"){
this.value = value;
this.status = RESOLVE;
console.log(this.onResolvedCallbacks)
this.onResolvedCallbacks.forEach(fn=>fn());
}
} // 不属于实例上的 是单独每个人都有的
let reject = (reason)=>{
if(this.status === "PENDING"){
this.reason = reason;
this.status = REJECT;
console.log(this.onRejectedCallbacks)
this.onRejectedCallbacks.forEach(fn=>fn());
}
}
// promise 发生了错误的逻辑也会 执行 失败
try{
executor(resolve,reject); // 这个是执行器 默认立即执行
}catch (e) {
console.log(e)
reject(e);
}
}
then(onFulfiled,onRejected){
console.log(1,this.onResolvedCallbacks)
console.log(1,this.onRejectedCallbacks)
if(this.status === RESOLVE){
onFulfiled(this.value);
}
if(this.status === REJECT){
onRejected(this.reason);
}
if(this.status === PENDING){
this.onResolvedCallbacks.push(()=>{
onFulfiled(this.value);
})
this.onRejectedCallbacks.push(()=>{
onRejected(this.reason);
})
}
}
}
module.exports = Promise;
promise 的 then的用法解析
let fs = require("fs");
// error first 错误第一 异步方法 无法通过 try catch 捕获异常
// fs.readFile("./name.text","utf8",(err,data)=>{
// console.log(data);
// if(err){}
// fs.readFile(data,"utf8",(err,data)=>{
// if(err){}
// console.log(data);
// })
// });
// 写法没有问题 但是错误处理麻烦
// promis 可以解决上面的问题
function read(fillname){
return new Promise((resolve, reject)=>{
fs.readFile(fillname,"utf8",(err,data)=>{
if(err)return reject(err)
resolve(data)
})
})
}
// 1.promise 的 成功或失败的回调的 返回值 可以传递到外层的 then
// 2. 如果返回值为普通值 可以当下一个回调 then 的参数 可能有 promise 的情况(采用 promis的状态 判断下一次的 成功或者失败) 还有 error的情况 出错就一点会走下一次的失败
// 3. 错误处理 如果 自己没有错误处理 他会向下查找
// 4. 每次执行完promise.then 方法后返回的都是一个 "promise" (promise 一旦成功或者失败就不能修改)
read("./name.txt").then((data)=>{
console.log(data);
return read(data);
},(err)=>{
console.log(err);
throw new Error("错误");
}).then((data)=>{
console.log("______",data);
},(err)=>{
console.log("____",err+"错误");
})
// 这样就是通过了 链式调用解决了回调 嵌套问题
普通值的处理
// promise 有三个状态 pending(等待态) resolve(成功态) reject(失败态)
let PENDING = "PENDING"; // 等待态
let RESOLVE = "RESOLVE"; // 成功态
let REJECT = "REJECT"; // 失败态
// promise 是个类 创建一个promise 类
class Promise {
constructor(executor) {
this.status = PENDING;
this.value = undefined; // 成功的原因
this.reason = undefined; // 失败的原因
this.onResolvedCallbacks = []; // 成功的回调函数 集合
this.onRejectedCallbacks = []; // 失败的回调函数 集合
let resolve = (value) => {
if (this.status === PENDING) {
this.value = value;
this.status = RESOLVE;
console.log(this.onResolvedCallbacks)
this.onResolvedCallbacks.forEach(fn => fn());
}
} // 不属于实例上的 是单独每个人都有的
let reject = (reason) => {
if (this.status === PENDING) {
this.reason = reason;
this.status = REJECT;
console.log(this.onRejectedCallbacks)
this.onRejectedCallbacks.forEach(fn => fn());
}
}
// promise 发生了错误的逻辑也会 执行 失败
try {
executor(resolve, reject); // 这个是执行器 默认立即执行
} catch (e) {
console.log(e)
reject(e);
}
}
// 1.promise 的 成功或失败的回调的 返回值 可以传递到外层的 then
// 2. 如果返回值为普通值 可以当下一个回调 then 的参数 可能有 promise 的情况(采用 promis的状态 判断下一次的 成功或者失败) 还有 error的情况 出错就一点会走下一次的失败
// 3. 错误处理 如果 自己没有错误处理 他会向下查找
// 4. 每次执行完promise.then 方法后返回的都是一个 "promise"(promise 一旦成功或者失败就不能修改)
then(onFulfiled, onRejected) {
// console.log(1, this.onResolvedCallbacks)
// console.log(1, this.onRejectedCallbacks,this.status)
let promise2 = new Promise((resolve,reject)=>{ // 为了实现链式调用
if (this.status === RESOLVE) {
let x = onFulfiled(this.value);
resolve(x);
}
if (this.status === REJECT) {
onRejected(this.reason);
}
if (this.status === PENDING) {
this.onResolvedCallbacks.push(() => {
onFulfiled(this.value);
})
this.onRejectedCallbacks.push(() => {
onRejected(this.reason);
})
}
})
return promise2
}
}
module.exports = Promise;
promise2状态的处理
// promise 有三个状态 pending(等待态) resolve(成功态) reject(失败态)
let PENDING = "PENDING"; // 等待态
let RESOLVE = "RESOLVE"; // 成功态
let REJECT = "REJECT"; // 失败态
let resolvePromise = (promise2,x,resolve,reject)=>{
console.log(promise2,x,resolve,reject);
}
// promise 是个类 创建一个promise 类
class Promise {
constructor(executor) {
this.status = PENDING;
this.value = undefined; // 成功的原因
this.reason = undefined; // 失败的原因
this.onResolvedCallbacks = []; // 成功的回调函数 集合
this.onRejectedCallbacks = []; // 失败的回调函数 集合
let resolve = (value) => {
if (this.status === PENDING) {
this.value = value;
this.status = RESOLVE;
console.log(this.onResolvedCallbacks)
this.onResolvedCallbacks.forEach(fn => fn());
}
} // 不属于实例上的 是单独每个人都有的
let reject = (reason) => {
if (this.status === PENDING) {
this.reason = reason;
this.status = REJECT;
console.log(this.onRejectedCallbacks)
this.onRejectedCallbacks.forEach(fn => fn());
}
}
// promise 发生了错误的逻辑也会 执行 失败
try {
executor(resolve, reject); // 这个是执行器 默认立即执行
} catch (e) {
console.log(e)
reject(e);
}
}
// 1.promise 的 成功或失败的回调的 返回值 可以传递到外层的 then
// 2. 如果返回值为普通值 可以当下一个回调 then 的参数 可能有 promise 的情况(采用 promis的状态 判断下一次的 成功或者失败) 还有 error的情况 出错就一点会走下一次的失败
// 3. 错误处理 如果 自己没有错误处理 他会向下查找
// 4. 每次执行完promise.then 方法后返回的都是一个 "promise"(promise 一旦成功或者失败就不能修改)
then(onFulfiled, onRejected) {
// console.log(1, this.onResolvedCallbacks)
// console.log(1, this.onRejectedCallbacks,this.status)
let promise2 = new Promise((resolve,reject)=>{ // 为了实现链式调用
if (this.status === RESOLVE) {
setTimeout(()=>{
try{
let x = onFulfiled(this.value);
resolvePromise(promise2,x,resolve,reject);
}catch (e) {
reject(e);
}
},0)
}
if (this.status === REJECT ) {
setTimeout(()=>{
try{
let x = onRejected(this.reason);
resolvePromise(promise2,x,resolve,reject);
}catch (e) {
reject(e);
}
},0)
}
if (this.status === PENDING) {
this.onResolvedCallbacks.push(() => {
setTimeout(()=>{
try{
let x = onFulfiled(this.value);
resolvePromise(promise2,x,resolve,reject);
}catch (e) {
reject(e);
}
},0)
})
this.onRejectedCallbacks.push(() => {
setTimeout(()=>{
try{
let x = onRejected(this.reason);
resolvePromise(promise2,x,resolve,reject);
}catch (e) {
reject(e);
}
},0)
})
}
})
return promise2
}
}
module.exports = Promise;
**完整的promise **
// promise 有三个状态 pending(等待态) resolve(成功态) reject(失败态)
let PENDING = "PENDING"; // 等待态
let RESOLVE = "RESOLVE"; // 成功态
let REJECT = "REJECT"; // 失败态
// resolvePromise 所有的 promise 都要遵循 bluebired q es6-romise
let resolvePromise = (promise2,x,resolve,reject)=>{
// console.log(promise2,x,resolve,reject);
// 循环引用
if(promise2 === x){
throw reject(new TypeError("TypeError: Chaining cycle detected for promise #<Promise>"))
}
let called = false;
if(typeof x === 'object' && x != null || typeof x === "function"){
// 要继续判断 有可能是 promise
try {
let then = x.then
if(typeof then === "function"){ // 只能认为是个 promise了
// x.then
then.call(x,y=>{ // 根据 promise 的成功就走成功,失败就走失败
if(called)return;
called = true;
resolvePromise(promise2,y,resolve,reject)
// resolve(y)
},e=>{
if(called)return;
called = true;
reject(e)
})
}else {
resolve(x)
}
}catch (e) {
// 防止失败了 再次成功
if(called)return;
called = true;
reject(e) // 异常抛出
}
}else {
resolve(x);
}
// 后续判断必须为严格模式 保证代码能和别的库 一起使用
}
// promise 是个类 创建一个promise 类
class Promise {
constructor(executor) {
this.status = PENDING;
this.value = undefined; // 成功的原因
this.reason = undefined; // 失败的原因
this.onResolvedCallbacks = []; // 成功的回调函数 集合
this.onRejectedCallbacks = []; // 失败的回调函数 集合
let resolve = (value) => {
if (this.status === PENDING) {
this.value = value;
this.status = RESOLVE;
console.log(this.onResolvedCallbacks)
this.onResolvedCallbacks.forEach(fn => fn());
}
} // 不属于实例上的 是单独每个人都有的
let reject = (reason) => {
if (this.status === PENDING) {
this.reason = reason;
this.status = REJECT;
console.log(this.onRejectedCallbacks)
this.onRejectedCallbacks.forEach(fn => fn());
}
}
// promise 发生了错误的逻辑也会 执行 失败
try {
executor(resolve, reject); // 这个是执行器 默认立即执行
} catch (e) {
console.log(e)
reject(e);
}
}
// 1.promise 的 成功或失败的回调的 返回值 可以传递到外层的 then
// 2. 如果返回值为普通值 可以当下一个回调 then 的参数 可能有 promise 的情况(采用 promis的状态 判断下一次的 成功或者失败) 还有 error的情况 出错就一点会走下一次的失败
// 3. 错误处理 如果 自己没有错误处理 他会向下查找
// 4. 每次执行完promise.then 方法后返回的都是一个 "promise"(promise 一旦成功或者失败就不能修改)
then(onFulfiled, onRejected) {
// console.log(1, this.onResolvedCallbacks)
console.log(1, this.onRejectedCallbacks,this.status)
onFulfiled = typeof onFulfiled === "function"? onFulfiled:v=>v;
onRejected = typeof onRejected === "function"? onRejected:err=>{throw err};
let promise2 = new Promise((resolve,reject)=>{ // 为了实现链式调用
if (this.status === RESOLVE) {
setTimeout(()=>{
try{
let x = onFulfiled(this.value);
resolvePromise(promise2,x,resolve,reject);
}catch (e) {
reject(e);
}
},0)
}
if (this.status === REJECT ) {
setTimeout(()=>{
try{
let x = onRejected(this.reason);
resolvePromise(promise2,x,resolve,reject);
}catch (e) {
reject(e);
}
},0)
}
if (this.status === PENDING) {
this.onResolvedCallbacks.push(() => {
setTimeout(()=>{
try{
let x = onFulfiled(this.value);
resolvePromise(promise2,x,resolve,reject);
}catch (e) {
reject(e);
}
},0)
})
this.onRejectedCallbacks.push(() => {
setTimeout(()=>{
try{
let x = onRejected(this.reason);
resolvePromise(promise2,x,resolve,reject);
}catch (e) {
reject(e);
}
},0)
})
}
})
return promise2
}
}
module.exports = Promise;