筹备工作

实现一个高阶函数

调用一个办法,在这个办法执行前先执行另一个办法

// AOP  切片编程function say(who){    console.log(who + '谈话了');}//在函数的原型对象上增加一个属性berfor 能够让每个函数都能调用Function.prototype.berfor = function(berforFunc){    return (...agrs)=>{        berforFunc()        this(...agrs)    }}let newFn = say.berfor(function(){    console.log('谈话之前');})newFn('我')// ======================================================let oldPush = Array.prototype.push;function push(...agrs){    // this ===》 arr    console.log('数据更新了');    oldPush.call(this,...agrs);  // call 1、扭转this指向  2、让函数执行}let arr = [1,2,3]// push(arr,4,5,6)   // 在这调用push办法时,this的指向是全局, 所以应用call  扭转this指向push.call(arr,4,5,6)   // 在这调用push办法时,this的指向是全局,对应的函数外部也是全副, 所以应用call  扭转this指向console.log(arr)

AOP

AOP(面向切面编程)的次要作用是把一些跟外围业务逻辑模块无关的性能抽离进去,其实就是给函数加一层,不必管函数外部实现

成果代码:

function perform(anyMethod,wrappers){    return function(){        wrappers.forEach(wrapper => wrapper.initialize())        anyMethod()        wrappers.forEach(wrapper => wrapper.close())    }}let newFn1 = perform(function(){    console.log('say')},[{        initialize(){            console.log('wrapper1 beforeSay')        },        close(){            console.log('wrapper1 close')        }    },    {        initialize(){            console.log('wrapper2 beforeSay')        },        close(){            console.log('wrapper2 close')        }    }])newFn1()// wrapper1 beforeSay// wrapper2 beforeSay// say// wrapper1 close// wrapper2 close

after 在 。。。 之后

// 利用闭包  保留times  在执行两次后才会输入function after(times,callback){    return function(){        if(--times === 0){            callback()        }    }}let fn = after(2, function(){    console.log('really')})fn();fn();

应用高阶函数解决异步问题的思路

let fs = require('fs')fs.readFile('./name.txt','utf8',function(err,res){    // console.log(res)    // 第一种办法应用    school.name = res    out()     // 第二种办法应用    out('name',res)})fs.readFile('./age.txt','utf8',function(err,res){    // console.log(res)    // 第一种办法应用    school.age = res    out()    // 第二种办法应用    out('name',res)})// 第一种 应用回调函数的办法  然而这个办法 会导致school裸露再里面  //都能够批改 school,所哟并不是黑号let school = {}function out(){    console.log(Object.keys(school))    if(Object.keys(school).length == 2){        console.log(school)    }}// 第二种 应用 上述after的办法来实现,,也就是闭包的模式let out = after(2, function(res){    console.log(res)})function after(times,callback){    let school = {}    return function(key,val){        school[key] = val        if(--times === 0){            callback(school)        }    }}

公布模式和订阅模式

let fs = require('fs')fs.readFile('./name.txt','utf8',function(err,res){    school.name = res    event.emit()})fs.readFile('./age.txt','utf8',function(err,res){    school.age = res    event.emit()})let event = {    _arr:[],    // 订阅    on:function(fn){        this._arr.push(fn)      },    // 公布    emit:function(fn){        this._arr.forEach(fn => fn())    }}let school = {}event.on(function(){    console.log('读取一个');})event.on(function(){    if(Object.keys(school).length == 2){        console.log(school)    }})

观察者模式 是基于公布订阅模式的

// 被观察者class Subject{    constructor(){        this.state = '开心'        this.arr = []    }    // 增加观察者    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 sub = new Subject('小宝宝')let my = new Observer('我')sub.attach(my)sub.setState('不开心')sub.setState('很开心')

开始promise

promise优缺点

  • 长处

    • 能够解决异步嵌套问题
    • 能够解决多个异步并发问题
  • 毛病

    • promise 基于回调 会不停的写函数
    • 无奈终止异步

    根本实现 与 then办法

/** * 1、(then中传递的函数)判断胜利和失败函数的返回后果 * 2、判断是不是promise 如果是promise 就采纳他的状态 * 3、如果不是promise 间接将后果传递上来即可 */const PENDING = 'PENDING'const FULFILLED = 'FULFILLED'const REJECTED = 'REJECTED'// 因为promise const resolvePromise = (_promise, x, fulfill, reject) => {    let called;    // x 和 promise 不能是同一个 promise mdn中有解释  将会进入死循环 (promise 标准)    if (x === _promise) {        return reject(new TypeError('Chaining cycle detected for promise #<Promise>'))    }    if (typeof x === 'object' && x !== null || typeof x === 'function') {        try {            let then = x.then // 取then 有可能then属性是通过 defineProperty来定义的            if (typeof then === 'function') {  // 当then是一个办法 就认为是promise                 then.call(x, y => {                     if(called) return;                    called = true                    resolvePromise(_promise, y, fulfill, reject)   // 参用promise 的胜利后果向下传 递归  晓得解析进去的是一个一般值                }, r => {                    if(called) return;                    called = true                    reject(r)    // 采纳失败后果向下传                }) // 能保障不必再次then的值            } else {                    fulfill(then) // 阐明x是一个一般对象            }        } catch (e) {            if(called) return;            called = true            reject(e)         }    } else {        fulfill(x)    }}class MyPromise {    // 1 看属性是否再原型上    // 2 看属性是否专用    constructor(executor) {        this.status = PENDING        this.value = undefined;        this.reason = undefined;        this.onFulfilledCallbacks = []; // 胜利的函数数组        this.onRejectedCallbacks = []; // 失败的函数数组        // 胜利函数        let fulfill = (value) => {            if (this.status === PENDING) {   // 屏蔽                this.value = value                this.status = FULFILLED                this.onFulfilledCallbacks.forEach(fn => fn())            }        }        // 失败函数        let reject = (reason) => {            console.log('reason: ' + reason)            if (this.status === PENDING ) {   // 屏蔽                this.reason = reason                this.status = REJECTED                this.onRejectedCallbacks.forEach(fn => fn())            }        }        try {            executor(fulfill, reject); // 默认执行器会立即执行        } catch (e) {            reject(e)  // 如果执行失败产生谬误  等价于调用了        }    }    // 传入两个参数       then(onFulfilled = data => data, onRejected) {        onRejected = typeof onRejected == 'function'? onRejected: err=>{throw err}        let _promise = new MyPromise((fulfill, reject) => {    // 实现then可能链式调用  返回一个本人的实例            if (this.status === FULFILLED) {                setTimeout(() => {  // 为了可能使_promise 实例化实现 所以应用setTimeout 等new完之后执行setTimeout                    try {                        let x = onFulfilled(this.value)                        // x 可能是一般值 有可能是promise                        // 判断x的值 => promise2的状态                        resolvePromise(_promise, x, fulfill, reject)                        // fulfill(x)                    } catch (e) {                        reject(e)                    }                }, 0)            }            if (this.status === REJECTED) {                setTimeout(() => {                    try {                        let x = onRejected(this.reason)                        resolvePromise(_promise, x, fulfill, reject)                    } catch (e) {                        reject(e)                    }                }, 0)            }            if (this.status == PENDING) {                // 如果是异步                   this.onFulfilledCallbacks.push(() => {                    setTimeout(() => {                        try {                            let x = onFulfilled(this.value)                            resolvePromise(_promise, x, fulfill, reject)                        } catch (e) {                            reject(e)                        }                    }, 0)                })                this.onRejectedCallbacks.push(() => {                    setTimeout(() => {                        try {                            let x = onRejected(this.reason)                            resolvePromise(_promise, x, fulfill, reject)                        } catch (e) {                            reject(e)                        }                    }, 0)                })            }        })        return _promise    }}// 提早对象MyPromise.defer = MyPromise.deferred = function(){    let dfd = {}    dfd.promise = new MyPromise((resolve,reject)=>{        dfd.resolve = resolve        dfd.reject = reject    })    return dfd}module.exports = MyPromiselet p = new MyPromise((resolve, reject) => {    resolve(100)})// let promise2 = p.then(data => {//     return new MyPromise((resolve, reject) => {//         setTimeout(() => {//             reject('hello')//         }, 0)//     })// })// promise2.then(data => {//     console.log('data:' + data)// }, err => {//     console.log('err:' + err)// })// p.then().then().then().then(data=>{//     console.log(data)// })// MyPromise.defer() 能够帮忙解决封装嵌套的问题let fs = require('fs')function read(url){    let dfd = MyPromise.defer()    fs.readFile(url,'utf8',function(err,res){        if(err)  dfd.reject(err)        dfd.resolve(res)    })    return dfd.promise}read('./name.txt').then(res=>{    console.log(res)})

实现promise.all() 办法(一种实现办法)

/** * promise.all() 全副 能够实现期待所有的异步执行完后  拿到对立的后果 * 解决异步并发 同步处理结果 */let MyPromise = require('./promise_then')  // 本人封装的promise let fs = require('fs')function read(url) {    let dfd = MyPromise.defer()    fs.readFile(url, 'utf8', function (err, res) {        if (err) dfd.reject(err)        dfd.resolve(res)    })    return dfd.promise}const isPromise = (val) => {    if ((typeof val == 'object' && val !== null) || typeof val === 'function') {        if (typeof val.then === 'function') {            return true        }    } else {        return false    }}MyPromise.all = function (values) {    return new MyPromise((resolve, reject) => {        let arr = []        let index = 0        let processData = (key, value) => {            arr[key] = value            if (++index === values.length) {                resolve(arr)            }        }        for (let i = 0; i < values.length; i++) {            let current = values[i]            if (isPromise(current)) {                current.then(res => {                    processData(i, res)                }, reject)            } else {                processData(i, current)            }        }    })}MyPromise.all([1, 2, 3, read('./name.txt'), 3, 4]).then(res => {    console.log('all:' + res)})// all:1,2,3,'zhufeng',3,4

实现promise.all() 办法(第二种办法)

/**  * promise.all() 全副 能够实现期待所有的异步执行完后  拿到对立的后果 * 解决异步并发 同步处理结果 */let MyPromise = require('./promise_then')let fs = require('fs')function read(url) {    let dfd = MyPromise.defer()    fs.readFile(url, 'utf8', function (err, res) {        if (err) dfd.reject(err)        dfd.resolve(res)    })    return dfd.promise}// read('./name.txt').then(res=>{//     console.log('read:'+res)// }) const isPromise = (val) => {    if ((typeof val == 'object' && val !== null) || typeof val === 'function') {        if (typeof val.then === 'function') {            return true        }    } else {        return false    }}MyPromise.all = function (values) {    return new MyPromise((resolve, reject) => {        let arr = []        let index = 0        let processData = (key, value) => {            arr[key] = value            if (++index === values.length) {                resolve(arr)            }        }        for (let i = 0; i < values.length; i++) {            let current = values[i]            if (isPromise(current)) {                current.then(res => {                    processData(i, res)                }, reject)            } else {                processData(i, current)            }        }    })}MyPromise.all([1, 2, 3, read('./name.txt'), 3, 4]).then(res => {    console.log('all:' + res)})