msforest / notebook

好记性不如烂笔头,记录知识的点点滴滴。
https://github.com/msforest/notebook/wiki
0 stars 0 forks source link

async2.6.1源码分析之asyncify #28

Open msforest opened 6 years ago

msforest commented 6 years ago

使同步函数变成异步函数操作,result通过callback传递出去

export default function asyncify(func) {
    if (isAsync(func)) {    // 判断是否是async/await函数
        return function (...args/*, callback*/) {
            const callback = args.pop()
            const promise = func.apply(this, args)
            return handlePromise(promise, callback)
        }
    }

    // 在func外层包了一层函数,使得func被延长演出的时间
    return initialParams(function (args, callback) {
        var result;
        try {
            result = func.apply(this, args);
        } catch (e) {
            return callback(e);
        }
        // if result is Promise object
        if (result && typeof result.then === 'function') {  // 判断是否是promise函数
            return handlePromise(result, callback)
        } else {
            callback(null, result);  // sync函数还是sync,并没有async
        }
    });
}

// 处理promise的结果,将result通过callback传出去,而不是then;保证了对外统一的接口
function handlePromise(promise, callback) {
    return promise.then(value => {
        invokeCallback(callback, null, value);
    }, err => {
        invokeCallback(callback, err.message ? err : new Error(err));
    });
}

function invokeCallback(callback, error, value) {
    try {
        callback(error, value);
    } catch (err) {
        setImmediate(e => { throw e }, err);
    }
}

// import initialParams from './internal/initialParams';
export default function initialParams(fn) {
    return function (...args/*, callback*/) {
        var callback = args.pop();
        fn.call(this, args, callback);
    };
}

处处皆闭包,处处皆尾调用