zoukankan      html  css  js  c++  java
  • 从co到koa01-co

    thunk

    • 他的发展是由函数的求值策略的分歧决定的,两种求值策略
      • 传值调用,在进入函数体之前就直接执行完,把值传进去
      • 传名调用,将表达式传入函数体,只在用到他的时候求值
    • 传名函数的编译器实现,其实就是放入一个临时函数,再将临时函数传入函数体,这个临时函数就叫做thunk函数
    • js语言是传值调用,他的thunk含义有些不同,js中,thunk函数替换的不是表达式,而是多参数函数,将它替换成单参数的版本,且只接受回调函数作为参数
    • 任何有回调的函数都是可以搞成thunk形式的,下面是一个简单的生成器
    var Thunk = function(fn){
        return function () {
          //先传入其他的参数初始化
          var args = Array.prototype.slice.call(arguments);
          //传入callback返回的函数
          return function(callback){
            args.push(callback);
            //实际调用的时候
            return fn.apply(this,args);
          }
        }
      }
      var readFileThunk = Thunk(fs.readFile);
      readFileThunk(fileA)(callback);
    

    generator

    • Generator是为JavaScript设计的一种轻量级的协程。它通过yield关键字,可以控制一个函数暂停或者继续执行generator函数
    function * hello (name) {
        yield 'your name is: ' + name
        return 'input name is: ' + name
    }
    
    const gen = hello('jinks')
    
    //your name is: jinks
    gen.next().value
    //input name is: jinks
    gen.next().value
    

    CO

    • co的根本目的:将异步操作跟在yield后面,当异步操作完成并返回结果后,再触发下一次next() 。跟在yield后面的异步操作需要遵循一定的规范thunks和 promises
    //简化版co
    const fs = require('fs')
    const Q = require('Q')
    const readdir = Q.denodeify(fs.readdir)
    
    //或者thunk规范
    const thunkify = require('thunkify')
    const readdir = thunkify(fs.readdir)
    
    function co(generator) {
        return function (fn) {
            fn = fn || function () {}
    
            const gen = generator()
           
            function next (err, result) {
                if(err) {
                    return fn(err)
                }
                
                const step = gen.next(result)
                
                if(!step.done) {
                    // thunk
                    step.value(next)
                    // promise
                    step.value.then(res => next(null, res)).catch(err => next(err))
                } else {
                    fn(null, step.value)
                }
            }
            next()
        }
    }
    
    function *test() {
        const result = yield readdir(dir)
    }
    
    co(test)((err, result) => {
        console.log(err, result)
    })
    
  • 相关阅读:
    文件File
    Vuex 模块化实现待办事项的状态管理
    浅谈jquery插件开发模式*****************************************************************************************
    git 详细的操作指南笔记
    Vue学习之路---No.5(分享心得,欢迎批评指正)
    Java 向Hbase表插入数据报(org.apache.hadoop.hbase.client.HTablePool$PooledHTable cannot be cast to org.apac)
    MongoDB -- 查询
    3 分钟学会调用 Apache Spark MLlib KMeans
    架构设计:负载均衡层设计方案(4)——LVS原理
    Linux内核:关于中断你须要知道的
  • 原文地址:https://www.cnblogs.com/jinkspeng/p/8602228.html
Copyright © 2011-2022 走看看