所以一般情况下 是不是前端要考虑的情况更多,更复杂?
不是的,后端通常使用多线程来解决耗时操作,一个耗时操作只能阻塞一个线程,其他线程还可以处理其他的请求。这样后端可以采用同步编程的方式,前面的代码肯定在后面代码之前执行,后面代码可以用前面代码的结果,逻辑上比较清晰。
但前端一个页面只有一个ui线程,没法多线程,耗时操作会阻塞整个浏览器页面。所以对于耗时操作,前端不能用同步的编程方式,只能用异步编程方式,用回调函数,层层嵌套的回调函数造成回调地狱,非常难以阅读和维护。所以前端逐步发展出对付异步编程的方法,最早的是Promise和Observable,后来的async/await,让异步代码看起来像是同步,但只是伪同步,代码还是比后端的真同步难写。
虽然前端没有多线程的同步互斥问题,但总的来说,异步代码总是比同步代码难写。
前端js异步编程也有一个好处,只用很少的线程,并发量大的时候效率更高,引起线程切换也很耗资源。所以后端也引进了异步编程,比如nodejs,还有play framework2也是异步的,利用了promise或者java8中类似promise的机制。
前端的 JS 解释引擎只有一个线程,相当于后端的主线程,其余线程均由浏览器进行实现,并暴露相应的 API 给 JS 执行引擎,这些 API 通常要求 JS 绑定一个函数,以便回传结果。事实上, JS 代码通常不会全程运行,而是函数绑定的事件发生之后,将函数语句放到调用栈里逐条执行。
至于孰难孰易,听说后端比较难咯。
你需要了解 JS 事件队列,宏任务和微任务相关的概念就好了,建议看下《Javascript 高级编程》或者《你不知道的 Javascript》里面对应的章节。等你明白了这些概念和运行方式后就不会觉得难了,跟多线程是完全不同的方式。
10 回答11.1k 阅读
15 回答8.4k 阅读
5 回答4.8k 阅读✓ 已解决
4 回答3.1k 阅读✓ 已解决
8 回答6.2k 阅读
2 回答2.6k 阅读✓ 已解决
3 回答5.1k 阅读✓ 已解决
单线程说的是js主线程,一个窗口除了js主线程还有ui渲染线程,事件触发线程,时间线程,http请求线程,js的异步效果其实还是多个线程协作完成的,比如发起一个http请求浏览器就会新开一个线程,等请求返回的时候把回调放到事件触发线程,主线程执行完了就从事件触发线程里找到刚放进去的回调执行,所以js事件一般是在主线程执行完毕后再执行;定时器的回调也是一个道理,不是定时多久就真的那么久才执行,要等主线程执行完毕,所以js主线程处理很占有CPU的操作,很容易引起线程阻塞,一般这种情况会采用worker新建一个线程,在新建的线程里执行耗时操作,执行完了通过postMessage把结果发送到事件触发线程,等待主线程调用。。。总之js的单线程指的是主线程,有点像别人说java没有指针,并不是java真没指针,只是不需要像c++那样自己定义指针。