madfour / blog-docs

一个备忘录罢了
https://madfour.cn
MIT License
5 stars 0 forks source link

请写出下列代码的打印结果(同异步问题) #24

Open madfour opened 3 years ago

madfour commented 3 years ago
function wait() {
  return new Promise(resolve =>
    setTimeout(resolve, 10 * 1000)
  )
}

async function main() {
  console.time();
  const x = wait();
  const y = wait();
  const z = wait();
  await x;
  await y;
  await z;
  console.timeEnd();
}
main();

new Promise是一个同步运算,会立即执行。.then里面的函数才是异步的(微任务)。

所以相当于同时发起了三个异步任务。遇到 await 时,总时间就是三个任务中耗时最长的那个,即10*1000,所以总时间是10s多一点点。

扩展:

function wait() {
  return new Promise(resolve =>
    setTimeout(resolve, 10 * 1000)
  )
}

async function main() {
  console.time();
  // 可以去除 const _,直接写成await wait()
  const x = await wait();
  const y = await wait(); 
  const z = await wait();
  // 每个都是都执行完才结,包括setTimeout(10*1000)的执行时间
  // 执行顺序 x->y->z 同步执行,x 与 setTimeout 属于同步执行
  console.timeEnd(); // default: 30099.47705078125ms

  console.time();
  const x1 = wait(); // x1,y1,z1 同时异步执行, 包括setTimeout(10*1000)的执行时间
  const y1 = wait(); // x1 与 setTimeout 属于同步执行
  const z1 = wait();
  await x1;
  await y1;
  await z1;
  console.timeEnd(); // default: 10000.67822265625ms

  console.time();
  const x2 = wait(); // x2,y2,z2 同步执行,但是不包括setTimeout(10*1000)的执行时间
  const y2 = wait(); // x2 与 setTimeout 属于异步执行
  const z2 = wait();
  x2,y2,z2;
  console.timeEnd(); // default: 0.065185546875ms
}
main();
madfour commented 3 years ago

理解任务队列(消息队列)

一种是同步任务(synchronous),另一种是异步任务(asynchronous)

// 请问最后的输出结果是什么?
console.log("A");
while(true){ }
console.log("B");

输出结果:A,因为这是同步任务,程序自上而下执行,遇到while()死循环,下面语法无法执行

// 请问最后的输出结果是什么?
console.log("A");
setTimeout(function(){
    console.log("B");
},0);
while(true){}

输出结果:A,

题目中的setTimeout()就是个异步任务。在所有同步任务执行完之前,任何的异步任务是不会执行的。

// new Promise(xx)相当于同步任务, 会立即执行, .then后面的是微任务
console.log('----------------- start -----------------');
setTimeout(() => {
    console.log('setTimeout');
}, 0)
new Promise((resolve, reject) =>{  // new Promise(xx)相当于同步任务, 会立即执行, .then后面的是微任务
    for (var i = 0; i < 5; i++) {
        console.log(i);
    }
    resolve();  
}).then(() => {  
    console.log('promise实例成功回调执行');
})
console.log('----------------- end -----------------');

// ----------------- start -----------------
// 0
// 1
// 2
// 3
// 4
// ----------------- end -----------------
// promise实例成功回调执行
// setTimeout

new Promise(xx)相当于同步任务, 会立即执行