复杂的异步嵌套逻辑

88 阅读2分钟

前言

我们在面试的时候,经常会到那种面试题,给你一段很复杂的代码,然后让你写出执行结果。这类面试题非常考验我们对异步事件队列的应用,当然面对这类问题也是需要一定的方法的。这篇文章就是主要介绍如何处理复杂的异步嵌套逻辑。

快速分析一个复杂的异步嵌套逻辑,并掌握分析方法

console.log(1);
setTimeout(() => {
  console.log(2);
  setTimeout(() => {
    console.log(8);
  })
  Promise.resolve().then(() => {
    console.log(3)
  });
});
new Promise((resolve, reject) => {
  console.log(4)
  setTimeout(() => {
    console.log(10);
  })
  resolve()
}).then(() => {
  console.log(5);
  Promise.resolve().then(() => {
    console.log(11)
  });
  setTimeout(() => {
    console.log(13);
  })
})
setTimeout(() => {
  Promise.resolve().then(() => {
    console.log(9)
  });
  console.log(6);
  setTimeout(() => {
    console.log(12);
  })
})
console.log(7);
// 浏览器环境执行结果
// 1
// 4
// 7
// 5
// 11
// 2
// 10
// 6
// 13
// 3
// 9
// 8
// 12
// node环境执行结果:
// 1
// 4
// 7
// 5
// 11
// 2
// 3
// 10
// 6
// 9
// 13
// 8
// 12

分析方法

  1. 从头至尾执行一次代码,根据分类规则分至不同队列,new Promise(function)也是立即执行。setTimeout的回调函数属于宏队列(macrotask),resolve的回调函数属于微队列(microtask);
// 栈区
console.log(1);
console.log(4);
console.log(7);

// 宏队列
() => {
  console.log(2);
  setTimeout(() => {
    console.log(8);
  })
  Promise.resolve().then(() => {
    console.log(3)
  });
}

() => {
    console.log(10);
}

() => {
  Promise.resolve().then(() => {
    console.log(9)
  });
  console.log(6);
  setTimeout(() => {
    console.log(12);
  })
}

// 微队列
() => {
  console.log(5);
  Promise.resolve().then(() => {
    console.log(11)
  });
  setTimeout(() => {
    console.log(13);
  })
}
  1. 优先执行微任务队列,微队列执行过程中产生的微队列和宏队列置于队列末尾排序执行,而宏队列产生的微队列和宏队列于新的队列中等待。
    执行微队列:(分类)
// 栈区
console.log(1);
console.log(4);
console.log(7);
///////
console.log(5);

// 微队列
() => {
    console.log(11)
}

// 宏队列
() => {
  console.log(2);
  setTimeout(() => {
    console.log(8);
  })
  Promise.resolve().then(() => {
    console.log(3)
  });
}

() => {
    console.log(10);
}

() => {
  Promise.resolve().then(() => {
    console.log(9)
  });
  console.log(6);
  setTimeout(() => {
    console.log(12);
  })
}
() => {
    console.log(13);
}
  1. 此时新增了一个微队列console.log(11), 因为是微队列产生的,继续执行:
// 栈区
console.log(1);
console.log(4);
console.log(7);
///////
console.log(5);
//////
console.log(11);

// 微队列


// 宏队列
() => {
  console.log(2);
  setTimeout(() => {
    console.log(8);
  })
  Promise.resolve().then(() => {
    console.log(3)
  });
}

() => {
    console.log(10);
}

() => {
  Promise.resolve().then(() => {
    console.log(9)
  });
  console.log(6);
  setTimeout(() => {
    console.log(12);
  })
}
() => {
    console.log(13);
}
  1. 执行完微队列后执行宏队列
// 栈区
console.log(1);
console.log(4);
console.log(7);
///////
console.log(5);
///////
console.log(11);
///////
console.log(2);
console.log(10);
console.log(6);
console.log(13);

// 微队列
() => {
    console.log(3)
}
() => {
    console.log(9)
}

// 宏队列
() => {
    console.log(8);
}
() => {
    console.log(12);
}
  1. 接下来先执行微任务队列后执行宏任务队列
// 栈区
console.log(1);
console.log(4);
console.log(7);
///////
console.log(5);
///////
console.log(11);
///////
console.log(2);
console.log(10);
console.log(6);
console.log(13);
///////
console.log(3);
console.log(9);
console.log(8);
console.log(12);

// 微队列


// 宏队列