Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

2020.9.28 Generator 自动执行 #4

Open
SampsonKY opened this issue Sep 28, 2020 · 0 comments
Open

2020.9.28 Generator 自动执行 #4

SampsonKY opened this issue Sep 28, 2020 · 0 comments
Assignees
Labels
ES6 New feature or request 未完成 每日一题

Comments

@SampsonKY
Copy link
Owner

基于 thunk 的自动执行

function thunk(fn){
    return (...args)=>{
        return (callback)=>{
            fn.call(this, ...args, callback)
        }
    }
}

function run(gen){
    let g = gen()
    
    function next(err, data){
        let ret = g.next(data)
        if(ret.done) return ret.value
        ret.value(next)
    }
    next()
}

// 示例
const fs = require('fs')
let readFileThunk = thunk(fs.readFile)

function *gen(){
    let r1 = yield readFileThunk('fileA')
    console.log(r1.toString())
    let r2 = yield readFileThunk('fileB')
    console.log(r2.toString())
}
run(gen)

基于 Promise 的自动执行

function promisify(fn){
    return (...args)=>{
        return new Promise((resolve, reject)=>{
            fn(...args, function(err, data){
                if(err) return reject(err)
                resolve(data)
            })
        })
    }
}

function run(gen){
    let g = gen()
    
    function next(data){
        let ret = g.next(data)
        if(ret.done) return ret.value
        ret.value.then((data)=>{
            next(data)
        })
    }
}

//示例
let readFile = promisify(fs.readFile)
function *gen(){
    let r1 = yield readFile('fileA')
    console.log(r1.toString())
    let r2 = yield readFile('fileB')
    console.log(r2.toString())
}
run(gen)

co 模块

function co(gen){
    var ctx = this

    return new Promise(function(resolve, reject){
        if(typeof gen === 'function') gen = gen.call(ctx)
        if(!gen || typeof gen.next !== 'function') return resolve(gen)

        onFulfilled()
        function onFulfilled(res){
            var ret
            try {
                ret = gen.next(res)
            } catch (e) {
                return reject(e)
            }
            next(ret)
        }

        function onRejected(err){
            var ret
            try {
                ret = gen.throw(err)
            } catch (e) {
                return reject(e)
            }
            next(ret)
        }

        function next(ret){
            if (ret.done) return resolve(ret.value);
            var value = toPromise.call(ctx, ret.value);
            //var value = ret.value
            if (value && isPromise(value)) return value.then(onFulfilled, onRejected);
            return onRejected(
              new TypeError(
                'You may only yield a function, promise, generator, array, or object, '
                + 'but the following object was passed: "'
                + String(ret.value)
                + '"'
              )
            );
        } 
    })
}

function isPromise(obj){
    return 'function' == typeof obj.then
}
@SampsonKY SampsonKY added ES6 New feature or request 每日一题 未完成 labels Sep 28, 2020
@SampsonKY SampsonKY self-assigned this Sep 28, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ES6 New feature or request 未完成 每日一题
Projects
None yet
Development

No branches or pull requests

1 participant