如何从程序执行时间体现async的异步性

bravility
  • 239

1.为了测试async的异步性能,写了如下代码(可直接在浏览器console或node上运行)

async function maptest(item) {
    console.time('x'+item);
    console.log(item);
    for(let i = 0; i< 100000; i++) {
        let name = "test";
    }
    console.timeEnd('x'+item);
    return 1;
}

var list = [1,2,3,4,5,6,7,8,9,0];

console.time('xall');
for(var i = 0; i < 10; i++)
{
    maptest(list[i]).then();
}
console.timeEnd('xall');

输出结果为:

1
x1: 1.18212890625ms
2
x2: 0.097900390625ms
3
x3: 0.0830078125ms
4
x4: 0.078857421875ms
5
x5: 0.078857421875ms
6
x6: 0.080078125ms
7
x7: 0.080078125ms
8
x8: 0.079833984375ms
9
x9: 0.0810546875ms
0
x0: 0.0791015625ms
xall: 3.309814453125ms
1.182+0.098+0.083+0.079+0.079+0.080+0.080+0.080+0.081+0.079=1.921 < 3.3

问:从执行时间来看,总执行耗时并不是最长的一次maptest执行耗时,反而是比所有maptest函数执行时间之和还长。async不是异步执行的吗,此处为何体现不出async的异步性能?另外,为什么x1的执行时间远远大于其他时间?

回复
阅读 934
4 个回答

JS线程始终只有一个。xall也不是执行的时间,只是返回的时间。

你试试在maptest开头加一行await null会怎样

测试你得有个对比吧,和promise对比,async也不是为了性能吧,应该是让你可以像写同步代码一样写异步代码;至于x1的执行时间远远大于其他时间,你每次循环做的事情一样,我猜v8的强大缓存能力帮你优化了

 function sleep(time) {
    return new Promise(function (resolve, reject) {
      setTimeout(function () {
        resolve()
      }, time)
    })
  }

  function testPromise(time) {
    let str = `test promise, ${time}s`
    console.time(str)
    sleep(time).then(() => {
      console.timeEnd(str)
    })
  }
  async function testAsync(time) {
    let str = `test await  , ${time}s`
    console.time(str)
    await sleep(time)
    console.timeEnd(str)
  }

  async function tests(tiemList) {
    for (let i = 0, len = tiemList.length; i < len; i++) {
      let time = tiemList[i]
      testAsync(time)
      // 等待上一布完成
      await sleep(time + 500)
      testPromise(time)
      // 等待上一布完成
      await sleep(time + 500)
    }
    console.log('测试完成')
  }
  let tiemList = [200, 600, 1000, 1400, 1800, 2200]
  tests(tiemList)

首先,不能说 async 是异步执行的,例如:

async function test () {
  console.log(1) // 同步执行
}
test() 
console.log(2) 
// 1 2

async 函数能够出让执行权力,先执行其它代码,适当时候再回来继续执行 async 剩余代码:

async function test () {
  console.log(1)  // 同步执行
  var p = new Promise(resolve => setTimeout(resolve, 100))
  await p  // 出让执行权力
  console.log(2)  // 异步执行
}
test()
console.log(3)
// 1 3 2

所以,你的代码都是同步执行的。多说几句,JS 执行线程是单线程,在执行线程上执行是无法体现异步的优势的,你可以试试用 Worker 来测试 async 函数。

async 的异步,指的是函数调用后 then 的触发是异步。
async 函数里边的代码还是同步的。

你知道吗?

宣传栏