zf-6-函数和promise(1天)

在这里插入图片描述

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链

// 练 敲
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值