返回

面试官啊,前端面试中的“同步异步”和“阻塞非阻塞”之间的差别到底在哪里?

前端

唉!你好前端面试!(ㄒoㄒ)

对于前端工程师而言,面试中关于“同步异步”和“阻塞非阻塞”的问题可谓是家常便饭。然而,这两对概念之间错综复杂的联系往往让人一头雾水,分不清彼此。别担心,让我们抛开晦涩难懂的技术术语,用通俗易懂的语言,一探究竟。

同步异步:消息通信机制

同步和异步关注的是消息通信的机制。在同步通信中,发送方会在收到接收方回应之前一直等待。就像在现实生活中,当我们和朋友面对面交谈时,我们必须等到对方说完话才能回应。而在异步通信中,发送方发送消息后,无需等待接收方回应即可继续执行其他任务。就好比发短信,我们可以直接发送消息,然后在对方回复前做自己的事情。

阻塞非阻塞:程序状态

阻塞和非阻塞关注的是程序在等待调用结果时的状态。阻塞调用意味着程序会一直等待结果返回,在此期间,程序无法执行其他任务。就好比在超市排队结账,我们必须等到前面的人结完账才能轮到我们。而非阻塞调用允许程序在等待结果返回的同时继续执行其他任务。就像在网上购物,我们可以在等待商品送达的同时继续浏览其他商品。

同步异步 VS 阻塞非阻塞

值得注意的是,同步异步和阻塞非阻塞并不是一对一的关系。同步通信可以是阻塞的,也可以是非阻塞的。例如,读取文件时,如果文件不存在,同步读取操作会一直阻塞,直到文件被创建或读取超时。异步通信也可以是阻塞的,例如,在事件循环中使用回调函数时,如果回调函数执行时间过长,程序可能会阻塞。

JavaScript中的异步非阻塞

在JavaScript中,asyncawait可以实现异步非阻塞编程。async函数会被分成两部分执行:await之前和await之后。await关键字会暂停函数的执行,直到其后的异步操作完成。虽然async函数是非阻塞的,但事件循环的机制并没有改变。

举个例子

假设我们有一个异步函数,需要从服务器获取数据。我们可以使用asyncawait来实现:

async function getData() {
  const data = await fetch('https://example.com/data');
  // 其他代码...
}

在这个例子中,getData函数是非阻塞的,因为它在等待fetch操作完成之前不会阻塞程序执行。

总结

理解“同步异步”和“阻塞非阻塞”之间的差别对于前端面试至关重要。记住,同步异步关注的是消息通信机制,而阻塞非阻塞关注的是程序在等待调用结果时的状态。在JavaScript中,asyncawait可以实现异步非阻塞编程。通过掌握这些概念,您一定能在前端面试中脱颖而出,让面试官眼前一亮。