异步瀑布模型的定时版本

4

我想要覆盖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个回答

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)
  })
}


1

兼容 async.jswaterfall()

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
您不需要修改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');
})

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接