zoukankan      html  css  js  c++  java
  • 高阶函数

    定义

    1. 函数的参数是函数(回调)
    2. 函数的返回值是函数(拆分)

    事务

    • 作用是在核心方法之前和之后都扩展
    • 注意:这里的事务是react中的概念,跟sql语句没有关系
    const perform = (anyMethod, warppers) => {
    	warppers.forEach( wrap => {
    		wrap.initilizae();
    	})
    	anyMethod();
    	warppers.forEach( wrap => {
    		wrap.close();
    	})
    }
    // 输出为您好1 您好2 说话 再见1 再见2
    perform(() => {
    	console.log('说话');
    }, [{
    		initilizae() {
    			console.log('您好1');
    		},
    		close() {
    			console.log('再见1');
    		}
    
    	},
    	{
    		initilizae() {
    			console.log('您好2');
    		},
    		close() {
    			console.log('再见2');
    		}
    
    	}
    ])
    

    call,apply,bind三者的区别

    • 相同点都是用来改变this的指向。
    • 不同点,call的参数是一个一个的接受,立即执行;apply是第一个是this要指向的对象,第二个对象为数组,立即执行;bind方法在IE 6-8不支持,不是立即执行,而是返回一个改变了上下文后的函数,需要主动调用。
    //例子:求数组中的最值 
    let arr1 = [1, 2, 19, 6];
    console.log(Math.max.call(null, 1,2,19,6)); // 19
    console.log(Math.max.call(null, arr1)); // NaN
    console.log(Math.max.apply(null, arr1)); //  19 直接可以用arr1传递进去
    
    

    延时函数(调用几次后执行)

    const deferred = (times, fn) => {
    	return () => {
    		if (--times === 0) {
    			fn();
    		}
    	}
    }
    let newFn = deferred(3,()=>{
    	console.log('三次后执行');
    })
    newFn();
    newFn();
    newFn(); // 这里调用攻击三次了,执行回调函数
    

    实例: 解决并发问题,核心是计数器

    let fs = require("fs"); // file system 读取文件 操作文件
    
    let school = {};
    
    function after(times,callback){ // 高阶函数, 发布订阅模式
        return function(){
            if(--times === 0){
                callback();
            }
        }
    }
    let out = after(2,function(){ // 将数量内置到after函数中,闭包 Promise.all
        console.log(school);
    });
    // 每次读取后 都调用out方法
    fs.readFile('./name.txt','utf8',function(err,data){
        school['name'] = data;
        out();
    })
    fs.readFile('./age.txt','utf8',function(err,data){
        school['age'] = data;
        out();
    })
    
     // 核心还是计数器
    // 计数器的方式
    // let index = 0;
    // function out(){
    //     index++;
    //     if(index === 2){
    //         console.log(school)
    //     }
    // }
    
    

    发布订阅

    • 有一个数组可以存放函数
    • 有一个订阅方法on,接受函数作为参数
    • 有一个触发方法emit,遍历数组中的函数
    let fs = require('fs');
    // 发布订阅 和 观察者模式的区别(基于发布订阅的) vue 观察者模式 es6的用法
    let school = {}; // vue eventBus
    let event = {
        arr:[], // 中介
        on(fn){
            this.arr.push(fn); // 把函数存到数组中,注意这里的this
        },
        emit(){
            this.arr.forEach(fn=>fn()); // 发布
        }
    }
    event.on(function(){
        console.log('读取一次')
    })
    event.on(function(){
        if(Object.keys(school).length === 2){
            console.log(school);
        }
    })
    fs.readFile('./name.txt','utf8',function(err,data){
        school['name'] = data;
        event.emit(); // 发布
    })
    fs.readFile('./age.txt','utf8',function(err,data){
        school['age'] = data;
        event.emit(); // 发布
    })
    

    发布订阅是观察者模式的一部分,
    发布和订阅是没有关系的,有一个数组作为第三方空间;
    观察者是观察者绑定了被观察者,也就是被观察者中有一数组存放着观察者对象,有关联关系。

    观察者

    • 两个对象,一个观察者,一个被观察者
    • 被观察者的构造函数中有一个数组存放观察者对象,有一个状态;有一个挂载观察者的方法,一个更新状态的方法
    • 观察者有一个更新的方法,当被观察者的状态更新的时候可以被调用
    // 被观察者 
    class Subject { 
        constructor(){
            this.arr = []; // 数组中存放的是观察者的实例
            this.state = '开心';
        }
        setState(newState){
            this.state = newState;
            this.arr.forEach(o=>o.update(this))
        }
        attach(o){ // 挂载观察者
            this.arr.push(o);
        }
    }
    
    // 观察者
    class Observer{ 
        constructor(name){ this.name = name;}
        update(s){ // 当前被观察者的状态发生了变化,需要更新状态了
            console.log(s.state+'对:'+this.name)
        }
    }
    let s = new Subject('小宝宝');  // 创建被观察者
    let o1 = new Observer('我'); // 创建两个观察者
    let o2 = new Observer('媳妇');
    s.attach(o1);
    s.attach(o2);
    s.setState('不开心')
    
    

    vue 观察者模式 eventBus 发布订阅

  • 相关阅读:
    读取STL模型 并用opengl显示
    金币阵列问题
    字典序问题的解决方案
    opengl中的旋转与平移
    copy文件夹,通过C++读取系统、用户名以及计算机名的方法
    poj3032
    菲涅尔反射(Fresnel Reflection)
    几个稍大场景的渲染测试
    Ward BRDF实现心得
    离线渲染中的不规则光源(Meshlight)
  • 原文地址:https://www.cnblogs.com/bonly-ge/p/11846247.html
Copyright © 2011-2022 走看看