美文网首页
回调函数的应用

回调函数的应用

作者: 静小弟 | 来源:发表于2020-03-05 08:32 被阅读0次
    • vscode插件
      • live server 起浏览器 通过localhost
      • code runner 可以运行部分代码

    callback

    高阶函数(aop 偏函数 柯里化)

    一个函数的参数是一个函数, 函数返回一个函数

    切函数,相当于在函数里面切一个口,放入自己的逻辑

    // 装饰器 前端埋点 在ajax中包装一层自己的逻辑
    // 判断this是谁,就要看.前面是谁 
    // 在原型上添加新的的方法
    Function.prototype.before = function (callback) {
        let self = this // 这个this指的是 fn
        return function (val) { // 这里可以用箭头函数
            callback() // before 的参数
            self(val)  // fn 的执行
        }
    }
    function fn(val) {
        console.log('一定功能'+ val)
    }
    fn.before(function(){
        cosole.log('在函数前面执行')
    })
    window.newFn('nihao') // this 为function 所以return 出来函数的this为window,将fn的this保存下来
    
    // after 函数 类似debounce throttle
    function after(times, callback) {
        return function () {
            if (--times === 0) { // 当i减到0,函数执行  
            callback()
        }
        }
    }
    after(3, callback)
    
    // 并发调用接口 两个ajax 使用after方法
    let fs = require('fs')
    function after(times, callback) {
        let result = {}
        return function (key, data) {
            result[key] = data
            if (--times === 0) {
                callback(result)
            }
        }
    }
    let newFn = after(2, funtion(result) {
       console.log(result)               
                      })
    fs.readFile('../name.txt', 'utf-8', (err, data) => {
        if (err) return console.log('err')
        newFn('name', data)
    })
    
    fs.readFile('../age.txt', 'utf-8', (err, data) => {
        if (err) return console.log('err')
        newFn('age', data)
    })
    
    
    // 串行 两个人有关系 上一个人的输出是下一个人的输入
    // 并行 两个人没有关系
    // 发布 订阅[fn, fn]  先订阅再发布
    let fs = require('fs')
    
    function EventEmitter () {
        this._arr = [] // 发布和订阅两个人是无关的,是靠中间媒介this._arr 
    }
    
    EventEmitter.prototype.on = function(callback) {
        this._arr.push(callback)
    }
    
    EventEmitter.prototype.emit = function () {
        this._arr.forEach(fn => fn。apply(this, arguments))
    }
    
    let e = new EventEmitter()
    
    let school = {}
    
    e.on(function(data, key) {
        school[key] = data;
        if (Object.keys(school).length === 2) {
            console.log(school)
        }
    })
    
    fs.readFile('../name.txt', 'utf-8', (err, data) => {
        if (err) return console.log('err')
        e.emit(data, 'name') // 在每个函数读完之后需要发布一次
    })
    
    fs.readFile('../age.txt', 'utf-8', (err, data) => {
        if (err) return console.log('err')
        e.emit(data, 'age') // 在每个函数读完之后需要发布一次
    })
    
    

    promise

    promise 规范 promise a+

    promise 是一个类 承诺 允诺 (异步解决方案)

    padding 等待状态 -> resolved 成功

    padding 等待状态 -> rejected 失败

    exexcutor 函数 而且会立即执行,参数是resolved reject

    每个promise实例有一个then方法

    let promise = new Promise ((resolve, reject) => {
        resolve('玩具少')
        reject('玩具多')
    })
    
    promise.then((val) => {
        console.log(val, 'success')
    }),function(err) {
        console.log(err, 'err')
    }
    
    • 手写promise
     function Promise (exexcutor) {
         this.state = 'padding'
         this.value = undefined;
         this.reason = undefined;
         let self = this;
         
         function resolve(value) {
             if (self.status === 'padding') {
                 self.value = value;
                 self.status = 'fulfilled'
         }
         
         function reject (reason) {
             if (self.status){
                 self.reason = reason;
                 self.status = 'resolved'
             }
         }
         // 执行器会立即执行
          try {         
         exexcutor(resolve, reject)
        } catch(e) {
            // 如果报错调用 then方法的reject方法
            reject(e)
        }
     
     Promise.prototype.then = function (onfulfilled, onrejected) {
         let self = this;
         if (self.status === 'fulfilled') {
             onfulfilled(self.value)
         }
         if (self.status === 'rejected') {
             onreject(self.reason)
         }
         if (self.status === 'padding') {
             
         }
     }
    
    
    // promise 的发布订阅
     function Promise (exexcutor) {
         this.state = 'padding'
         this.value = undefined;
         this.reason = undefined;
         let self = this;
         // 定义两个队列 存放对应的回调
         self.onResolveCallbacks = [] // 成功的回调
         self.onRejectCallbacks = [] // 失败的回调
         function resolve(value) {
             if (self.status === 'padding') {
                 self.value = value;
                 self.status = 'fulfilled'
                 self.onResolveCallbacks.forEach(fn => fn()) // 发布
         }
         
         function reject (reason) {
             if (self.status){
                 self.reason = reason;
                 self.status = 'resolved'
             }
         }
         // 执行器会立即执行
          try {         
         exexcutor(resolve, reject)
        } catch(e) {
            reject(e)
        }
     
     Promise.prototype.then = function (onfulfilled, onrejected) {
         let self = this;
         if (self.status === 'fulfilled') {
             onfulfilled(self.value)
         }
         if (self.status === 'rejected') {
             onreject(self.reason)
         }
         if (self.status === 'padding') { // 如果是异步的时候, 需要把成功和失败 分别存放到数组里,发布订阅,如果稍后调用了resolve 会热按函数依次执行,执行的时候 会将成功或者失败的的值进行传递
             this.onResolveCallbacks.push(function (){
                 onfulfilled(self.value)
             }) // 收集成功的回调  发布
             this.onRejectCallbacks.push(function(){
                 onrejected(self.reason)
             }) // 收集失败的回调  发布
         }
     }
    
    • promise 的链式调用
      • 如果then方法中返回的是一个promise 那我就采用这个promise的状态 作为成功哄着失败,把promise的结果作为参数
      • 如果返回的是一个普通值 直接作为下一个then的成功的参数
      • 在then方法中抛出异常 也会走失败,如果错误中 返回一个普通值 也会变成成功态
    • 每个then方法都返回一个新的promise
    
    

    generator

    generator生成器 iterator迭代器 (迭代器有一个next方法,每次都用后都会返回value, done 两个属性)

    生成器生成迭代器

    // 类数组 有数组 有索引 是个对象 能被迭代

    // 给一个对象添加迭代器功能 可以使他被迭代

    // 迭代器
    let obj = {0:1, 1:2, 2:3, length:3, [Symbol.itertor]: function() {
        let self = this;
        let index = 0
        return {
            next() {
                return {value: self[index], done: index++ === self.length}
            }
        }
    }}
    
    • 生成器返回的是迭代器 迭代器有next方法 调用next可以返回 value 和done
    function* read () { // 生成器
        yield 1
        yield 2
        yield 3
    }
    let it = read()
    console.log(it.next()) // 第一次next是不能传递参数
    console.log(it.next())
    console.log(it.next())
    
    // 改写上面的迭代器函数
    let obj = {0:1, 1:2, 2:3, length:3, [Symbol.iterator]: function *() {
        // 每次浏览器都会不停的调用next方法 把yield的结果作为值
        let index = 0;
        while(index !== this.length) {
            yield this[index ++]
        }
    }}
    

    async await

    相关文章

      网友评论

          本文标题:回调函数的应用

          本文链接:https://www.haomeiwen.com/subject/qrttrhtx.html