2016-12-19 23 views
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 

回答

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

这个怎么样?

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

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