8.javascript异步和同步

  • 说异步和同步的时候,讲一下并发和并行。计算中并行和并发是不同的概念,对应parallel和concurrent。
  1. 并行:举个栗子一个4核8线程的计算机,这时候同时有8个程序运行,每个程序占用一个线程,那么现在可以说这8个程序是并行的,同时走的。
  2. 并发:如果程序超过8个,超过的程序会停住吗。例如播放音乐和打字,难道我要打字完成了,才能播放音乐。或者音乐播放完成了,我才能打字。不cpu是以时间片轮询的方式,来执行的,就是等你打字的时候,偷偷去放音乐,放音乐的时候可以让你偷偷的打字,你却感觉不到卡顿,或者感觉不到音乐会不流畅,因为cpu速度太快了,已经超过了你的感知范围。很强!所以把这种程序交替运行叫做并发。
    也是和这个文章的看法一致:https://www.cnblogs.com/liu-runda/p/12599297.html
  • 在说说进程、线程
  1. 进程:是资源分配的最小单位。多进程,举个栗子,一台电脑开了QQ、微信、迅雷等等软件。
  2. 线程:是CPU调度的最小单位。多线程,QQ你打开了多个聊天窗口。
    在CPU比较繁忙,资源不足的时候(开启了很多进程),操作系统只为一个含有多线程的进程分配仅有的CPU资源,这些线程就会为自己尽量多抢时间片,这就是通过多线程实现并发,线程之间会竞争CPU资源争取执行机会。
    在CPU资源比较充足的时候,一个进程内的多线程,可以被分配到不同的CPU资源,这就是通过多线程实现并行
    至于多线程实现的是并发还是并行?上面所说,所写多线程可能被分配到一个CPU内核中执行,也可能被分配到不同CPU执行,分配过程是操作系统所为,不可人为控制。所有,如果有人问我我所写的多线程是并发还是并行的?我会说,都有可能
    这篇文章讲了多进程和多线程的选择:https://blog.csdn.net/yu876876/article/details/82810178可以参考下。
  • 你应该知道,javascript语言是一门“单线程”的语言,不像java语言,类继承Thread再来个thread.start就可以开辟一个线程,所以,javascript就像一条流水线,仅仅是一条流水线而已,要么加工,要么包装,不能同时进行多个任务和流程。一个web请求就是一个线程。
  • 现在我们在说到同步和异步
    同步:简单说就是代码顺序执行,遇到耗时操作代码会停住等待(python是同步的)。
    异步:多个函数同时执行时候,a函数需要等待,后面的b函数可以跳过等待继续执行(js默认是异步执行的)。
    前端需要使用异步的场景是哪些(需要等待的时候):
    定时任务:setTimeout,setInterval
    绑定事件:addEventListener(click等等)
    网络请求:ajax和img动态加载

上面说到了js是单线程和默认又是异步执行,这不是自相矛盾吗?
其实,单线程和异步确实不能同时成为一个语言的特性。js选择了成为单线程的语言,所以它本身不可能是异步的,但js的宿主环境(比如浏览器,Node)是多线程的,宿主环境通过某种方式使得js具备了异步的属性。这篇文章讲述了js的异步是通过宿主环境来实现的:https://www.cnblogs.com/woodyblog/p/6061671.html
javascript是如何实现异步的:https://www.jianshu.com/p/1a35857c78e5
既然js是异步执行的我们就需要控制,实现异步,哪一些先执行哪一些后执行。主流的解决方法主要有以下几种:

  1. 回调函数
function doSomething(callback){
  setTimeout(function(){
    console.log('执行结束');
    let result = 4;
    callback(result);
  },100);
}
function callback(result){
  console.log('接收到结果为:'+result);
}
doSomething(callback);
doSomething((result)=>{console.log('接收到结果为:'+result)});
  1. async(ES7)
function doSomething(){
  return new Promise(resolve=>{
    setTimeout(function(){
      let result = 6;
      resolve(result);
    },100);
  });
 
}
 
async function action(){
  let result = await doSomething();
  console.log(result);
}
action();
  1. 发布/订阅者模式
    观察者模式和发布订阅模式区别:https://www.cnblogs.com/leaf930814/p/9014200.html
    computed&watch&观察者模式:https://blog.csdn.net/vv_bug/article/details/102519987

  2. promise

function doSomething(){
  return new Promise(function(resolve){
    setTimeout(function(){
      console.log('执行结束');
      let result = 6;
      resolve(result);
    },100);
  });
 
}
doSomething().then(result=>{
  console.log('接收到结果为:'+result);
});
  1. generate函数,参考:https://www.cnblogs.com/lfxiao/p/9360476.html
function doSomething(){
  setTimeout(function(){
    let result = 6;
    it.next(result);
  },100);
}

function *gener(){
  var result = yield doSomething();
  console.log(result);
}

let it = gener();
it.next();
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容