【问题标题】:How to measure the execution time of an asynchronous function in nodejs?如何测量nodejs中异步函数的执行时间?
【发布时间】:2020-07-16 00:49:08
【问题描述】:

我正在尝试获取在节点获取操作中执行的异步函数的执行/响应时间,如下所示

async function getEditedData() {      
       var a = await fetch(`https://api.example.com/resorce_example`);
       var b = await a.json();
       // Some aditional treatment of the object obtained (b)
       console.log("End of the asynchronous function")
}

我这样使用库perf_hooks,但是执行时间显示在之前

const hrtime = require ('perf_hooks').performance.now ;
var start = hrtime ();
   getEditedData();
var end   = hrtime ();
console.log (end - start);

我找到了 async_hooks 库 https://nodejs.org/api/perf_hooks.html#perf_hooks_measuring_the_duration_of_async_operations ,但我不明白它是如何工作的。我是 javascript/nodejs 的基础

【问题讨论】:

  • getEditedData().then(() => console.log(hrtime() - start))
  • await.then().catch()。与调用任何异步函数没有什么不同。

标签: javascript node.js performance async-await measure


【解决方案1】:

您可以简单地将 Date.now() 存储在某个变量中,然后在您的 Promise 解决(或拒绝)时检查 Date.now() 并减去以找出差异。例如:

const simulateSomeAsyncFunction = new Promise((resolve, reject) => {
  console.log('Initiating some async process, please wait...')
  const startTime = Date.now();

  setTimeout(() => {
    resolve(Date.now() - startTime);
  }, 3000);
});

simulateSomeAsyncFunction.then(msElapsed => {
  console.log(`Async function took ${msElapsed / 1000} seconds to complete.`);
});

注意:您可以使用await/async 编写实现相同目标并且看起来是同步的代码,因为这只是构建在 Promises 之上的“语法糖”。例如:

const simulateSomeAsyncFunction = () => {
  console.log('Initiating some async process, please wait...');

  return new Promise((resolve, reject) => {
    setTimeout(resolve, 3000);
  });
};

// Await is required to be called within an async function so we have to wrap the calling code in an async IIFE
(async() => {
  const startTime = Date.now();

  await simulateSomeAsyncFunction();

  const msElapsed = Date.now() - startTime;

  console.log(`Async function took ${msElapsed / 1000} seconds to complete.`);
})();

【讨论】:

    【解决方案2】:

    如果您希望在getEditedData() 完成后设置end,您实际上需要await getEditedData()。否则,你会在它执行时直接跳过它……异步。

    【讨论】:

      【解决方案3】:

      从一个简单的异步函数开始 -

      const fakeAsync = async (value) => {
        const delay = 2000 + Math.random() * 3000 // 2 - 5 seconds
        return new Promise(r => setTimeout(r, delay, value))
      }
      
      fakeAsync("foo").then(console.log)
      
      console.log("please wait...")
      
      // "please wait..."
      // "foo"

      我们可以编写一个通用函数timeit。这是一个高阶函数,它接受一个函数作为输入并返回一个新函数作为输出。新功能的运行方式类似于原始功能的修饰版本 -

      const timeit = (func = identity) => async (...args) => {
        const t = Date.now()
        const result = await func(...args)
        return { duration: Date.now() - t, result }
      }
      
      // decorate the original
      const timedFakeAsync = timeit(fakeAsync)
      
      // call the decorated function
      timedFakeAsync("hello").then(console.log)
      timedFakeAsync("earth").then(console.log)
      
      // { duration: 3614, result: "earth" }
      // { duration: 4757, result: "hello" }
      

      我们函数的定时版本返回一个对象,{ duration, result },它报告我们异步函数的运行时间和结果。

      展开下面的sn-p,在自己的浏览器中验证结果-

      const identity = x =>
        x
      
      const timeit = (func = identity) => async (...args) => {
        const t = Date.now()
        const result = await func(...args)
        return { duration: Date.now() - t, result }
      }
      
      const fakeAsync = async (value) => {
        const delay = 2000 + Math.random() * 3000 // 2 - 5 seconds
        return new Promise(r => setTimeout(r, delay, value))
      }
      
      const timedFakeAsync = timeit(fakeAsync)
      
      timedFakeAsync("hello").then(console.log)
      timedFakeAsync("earth").then(console.log)
      
      console.log("please wait...")
      
      // "please wait..."
      // { duration: 3614, result: "earth" }
      // { duration: 4757, result: "hello" }

      【讨论】:

        猜你喜欢
        • 2019-03-30
        • 1970-01-01
        • 2017-10-23
        • 2021-05-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-15
        相关资源
        最近更新 更多