异步瀑布的定时版本

时间:2016-12-19 12:50:52

标签: javascript async.js

我想覆盖async.waterfall()(或写timed_waterfall()),以便打印每一步的执行时间。怎么做?

async.waterfall([
    f=>{
        console.log('step1');
        f();
    },
    f=>{
        console.log('step2');
        f();
    },
    f=>{
        console.log('step3');
        f();
    },
],
()=>{
    console.log('done');
})

期望的输出:

step1
1ms
step2
2ms
step3
1ms
done
5ms

3 个答案:

答案 0 :(得分:1)

async.js waterfall()兼容:

function timed_waterfall(tasks, ender) {
    function color(a) {
        if (a == undefined) { return '\u001b(B\u001b[m' }  
        return '\u001b[38;5;'+a+'m'
    }

    var N = 0;

    function go(args) {
        function f() {
            if (N>0)console.timeEnd(color(1)+' * '+N+color())
            var res = Array.prototype.slice.apply(arguments);
            if (res[0]) {
                ender.apply(null, res);
            }
            else {
                res.splice(0, 1);
                var cb = tasks.shift();
                if (cb) {
                    res.push(f);
                    console.time(color(1)+' * '+(++N)+color())
                    cb.apply(null, res);
                }
                else {
                    res.unshift(null)
                    ender.apply(null, res);
                }
            }
        }
        f(null);
    }
    go([]);
}

很容易修改以打印总数。

答案 1 :(得分:1)

这个怎么样?



function timedWaterfall (tasks, callback) {
  console.time('total')
  async.waterfall(tasks.map(function (task, i) {
    return function () {
      if (i > 0)
        console.timeEnd('step' + i)
       console.time('step' + (i + 1))
       return task.apply(null, arguments)
    }
  }),
  function () {
    console.timeEnd('total')
    callback.apply(null, arguments)
  })
}




答案 2 :(得分:1)

您根本不需要修改waterfall - 只需编写一个包装函数,为任务添加时间(回调函数):

function withTiming(fn, name) {
    if (typeof name == "number") name = "step"+name;
    return function() {
        var start = Date.now()
        var lastIndex = arguments.length-1;
        var cb = arguments[lastIndex];
        arguments[lastIndex] = function() {
            console.log(name+": "+(start-Date.now())+"ms");
            cb.apply(this, arguments);
        };
        return fn.apply(this, arguments);
    };
}

你可以像这样使用async.js:

async.waterfall([
    f=>{
        console.log('step1');
        f();
    },
    f=>{
        console.log('step2');
        f();
    },
    f=>{
        console.log('step3');
        f();
    },
].map(withTiming), ()=>{
//^^^^^^^^^^^^^^^
    console.log('done');
})