向generator函数传递参数

我们修改一下第一节提出的问题,现在,不再是固定统计 file1.mdfile2.mdfile3.md 三个文件的大小,而是支持任意传递任意的文件序列进行统计,显然,我们就要允许 generator 函数允许接收参数:

function *main(files) {
    // 初始化信息
    const sizeInfo = files.reduce((info, file) => {
        info[file] = 0;
        return info;
    }, {});

    try{
        const requests = files.map((file) => {
            return size(file);
        });

        sizes = yield requests;

        sizes.forEach((size, index) => {
            sizeInfo[files[index]] = sizes[index];
        });

        return sizeInfo;
    } catch(error) {
        console.error('error:', error);
    }
}

当我们通过wrap包装generator函数后,希望能以如下方式调用包装后的函数,驱动generator的运行:

wrap(main)(['file1.md', 'file2.md', 'file3.md'], function(err, sizeInfo){
    if(err) {
        console.error(err);
    } else {
        console.dir(sizeInfo);
    }
});

在这种调用方式中,我们规范最后一个参数为固定的回调函数,其余皆为传递给 generator 函数的参数,为此,我们需要修改 wrap 包装器,让其在调用 generator 函数时,将参数交付:

function wrap(gen) {
    return function (cb) {
        const args = Array.prototype.slice.call(arguments);
        const length = args.length;
        // 判断最后一个参数是否为回调函数
        if(length && 'function' === typeof args[length-1]) {
            cb = args.pop();
            it = gen.apply(this, args);
        } else {
            return;
        }
        // 驱动generator运行
        next();

        function next(err, res) {
            if(err) {
                return it.throw(err);
            }

            const { value, done } = it.next(res);
            if(done) {
                cb(null, value);
            }
            thunk = toThunk(value);
            if(typeof thunk === 'function') {
                thunk.call(this, function(err, res) {
                    if(err) {
                        next(err, null);
                    } else {
                        next(null, res);
                    }
                });
            }
        }
    }
}

results matching ""

    No results matching ""