课程咨询 :186 8716 1620      qq:2066486918

昆明Java培训 > 达内新闻 > 使用 ES6 来为异步函数记录执行时间
  • 使用 ES6 来为异步函数记录执行时间

    发布:昆明Java培训      来源:伯乐      时间:2016-07-05

  • 在这篇文章里,昆明达内java培训的老师会用一个可重用的函数来处理JavaScript延时异步操作。

    昆明达内java培训

    calc是一个我们想要做剖析(性能分析)的异步函数。按照惯例,它的最后一个参数是一个callback。我们像这样使用calc:

    calc(arg, (err, res) => console.log(err || res))

    或许,最简单的对calc这样的函数来剖析性能的方法是,增加一个计时逻辑到我们需要分析的地方:

    const t0 = Date.now()

    calc(arg, (err, res) => {

    const t1 = Date.now()

    console.log(`Log: time: ${t1 = t0}`)

    console.log(err || res)

    })

    但是,这不是一个可复用的解决方案。每一次我们想要对一个函数计时,我们得引入一个t0在外层作用域并且改变callback来测量和记录时间。

    对我来说理想的方式是能够仅仅通过包装一个异步函数就能够对它进行计时:

    timeIt(calc)(arg, (err, res) => console.log(err || res))

    timeIt需要能够很好地对每一个异步函数完成剖析和记录执行时间。

    注意到timeIt(calc)有与原始的calc函数同样的函数签名,即它们接受同样的参数和返回同样的值,它只是增加了一个特性到cale上(能够被记录时间的特性)。

    calc和timeIt(calc)在任意时刻可以相互替代。

    timeIt本身是一个高阶函数,因为它接受一个函数并返回一个函数。在我们的例子里,它接受calc异步函数,并返回一个函数与calc有同样的参数和返回值。

    下面演示我们如何实现timeIt函数:

    const timeIt1 = timeIt(

    (t, err, res) => console.log(`Log: ${err || res} produced after: ${t}`)

    )

    const calc = (x, y, z, callback) =>

    setTimeout(() => callback(null, x * y / z), 1000)

    calc(18, 7, 3, (err, res) => console.log(err || res))

    timeIt1(calc)(18, 7, 3, (err, res) => console.log(err || res))

    达内java的老师使用了神奇的Ramda库。你可以在Ramda REPL执行上面这段代码。

    这个timeIt实现接受两个参数:

    •report:一个函数用来生成剖析结果

    •f:我们想要做剖析的异步函数

    timeIt1是一个方便实用的功能函数,它只是用console.log记录时间测量结果。我们通过给更通用的timeIt函数传入report参数来定义它。

    我们实现了目标,现在我们可以仅仅将异步函数包装在timeIt1中就可以对它计时了:

    timeIt1(calc)(18, 7, 3, (err, res) => console.log(err || res))

    通用的timeIt函数接收一个report回调函数和一个异步函数并返回一个新的异步函数,这个异步函数与原函数有同样的参数和返回值。我们可以这么使用:

    timeIt(

    (time, ...result) => // report callback: log the time

    , asyncFunc

    )(

    parameters…,

    (...result) => // result of the async function

    )

    现在让我们深入timeIt的实现。我们可以简单地生成一个通用函数类似timeIt1,因为timeIt使用R.curry科里化了。

    我不打算在这篇文章里讨论科里化,但是下面这段代码演示了科里化的主要用法:

    const f = R.curry((x, y) => x + y)

    f(1, 10)  // == 11

    f(1)(10)  // == 11

    const plus1 = f(1)

    plus1(10) // == 11

    另一方面,这种方式实现的timeIt有几个问题:

    (...args) => {

    const t1 = Date.now()

    callback(...args)

    report(t1 — t0, ...args)

    }

    这是一个匿名函数(又名lambda,callback),它在原函数异步执行之后被调用。主要的问题是这个函数没有处理异常的机制。如果callback抛出异常,report就永远不会被调用。

    我们可以添加一个try / catch到这个lambda函数里,然而问题的根源是callback和report是两个void函数,它们没有关联在一起。timeIt包含两个延续(continuations)(report和callback)。如果我们只是在console下记录执行时间或者如果我们确定 论report还是callback都不会抛出异常,那么一切正常。但是如果我们想要根据剖析结果来执行一些行为(所谓的自动扩容)那么我们需要强化和厘清我们的程序中的延续序列。

    联系昆明达内java培训的老师,让你更加的全面的学会java的课程和经验!

    推荐文章

上一篇:昆明达内春城路中心java1606-2班开班啦!

下一篇:Java基础知识——java概述

最新开班日期  |  更多

Java--零基础全日制班

Java--零基础全日制班

开班日期:11/30

Java--零基础业余班

Java--零基础业余班

开班日期:11/30

Java--周末提升班

Java--周末提升班

开班日期:11/30

Java--零基础周末班

Java--零基础周末班

开班日期:11/30

  • 网址:http://km .java.tedu.cn      地址:昆明市官渡区春城路62号证券大厦附楼6楼
  • 课程培训电话:186 8716 1620      qq:2066486918    全国服务监督电话:400-827-0010
  • 服务邮箱 ts@tedu.cn
  • 2001-2016 达内国际公司(TARENA INTERNATIONAL,INC.) 版权所有 京ICP证08000853号-56