js异步编程

js异步编程

一、概念-什么是异步编程

callback async/await promise generator

说说js是单线程的

为什么是单线程

JavaScript单线程,在同一个时间内只能做一件事。作为浏览器脚本语言,JavaScript的主要用途是与用户互动,以及操作DOM。比如,假定JavaScript同时有两个线程,一个线程在某个DOM节点上添加内容,另一个线程删除了这个节点,这两个操作是矛盾的,这时浏览器应该以哪个线程为准?所以说,多线程会带来很复杂的同步问题,为了避免问题的产生,由此决定了js是单线程的。
小插曲:浏览器是多线程浏览器,很多异步行为都是由浏览器新开一个线程去完成。javascript引擎线程是浏览器多个线程中的一个,它本身是单线程的。浏览器还包括很多其他线程,如界面渲染线程,浏览器事件触发线程,Http请求线程等。
所以,所谓的javascript是单线程的,是指javascript运行在浏览器中是单线程的,叫做javascript引擎线程。

js单线程弊端

单线程不能并行处理任务,所有的任务都需要排队,前面一个任务没有执行完,后面一个任务无法执行,假如在前一个任务中很耗时,执行了很久,后一个任务还得等着,整个程序都会卡在那儿了。所以可以通过异步编程,来处理耗时的任务,比如ajax请求数据。
因为单线程的弊端所以js语言将任务的执行模式分为同步和异步模式
- 同步模式:”同步模式”就是上一段的模式,后一个任务等待前一个任务结束,然后再执行,程序的执行顺序与任务的排列顺序是一致的、同步的;
- 异步模式:”异步模式”则完全不同,每一个任务有一个或多个回调函数(callback),前一个任务结束后,不是执行后一个任务,而是执行回调函数,后一个任务则是不等前一个任务结束就执行,所以程序的执行顺序与任务的排列顺序是不一致的、异步的。
- 同步模式和异步模式比较,为什么异步模式很重要
“异步模式”非常重要。js只有一根线程,如果没有异步编程,非得卡死啊。在浏览器端,耗时很长的操作都应该异步执行,避免浏览器失去响应,最好的例子就是Ajax操作。在服务器端,”异步模式”甚至是唯一的模式,因为执行环境是单线程的,如果允许同步执行所有http请求,服务器性能会急剧下降,很快就会失去响应。
- 在以上的基础上,阐述异步编程是什么


二、处理异步编程的几种方式

1、callback,这是异步编程最基本的方法。
优势:回调函数的优点是简单、容易理解和部署
劣势:多个回调函数嵌套,各个部分之间高度耦合,流程会很混乱,而且每个任务只能指定一个回调函数。
eg:

fs.readFile(fileA, (err, data) => {
  fs.readFile(fileB, (err, data) => {
    // ...
  });
});

ps:如果嵌套多层,会出现“回调地狱”,代码是横向发展的,不利于代码的阅读和维护,难以管理。
2、事件监听
3、观察者模式,js设计模式
ps:事件监听 和发布/订阅 内部实现,原理是一样的。发布/订阅其实也是事件。
4、promise:
简单理解:每个异步任务都会返回promise对象,此对象有then方法,可以指定回调函数。
基于第一点提的“回调地狱”的情况时,promise可以解决,它是一种新的写法,而不是一种语法。
eg:f1().then(f2).(f3);
ps:then方法加载回调函数,catch方法捕捉执行过程中抛出的错误
相比于以上传统的解决方案,promise作为异步编程的一种解决方案,更加强大。不过看上去一堆”then”,也很不爽啊。
爬坑:
低版本的ie不支持es6 promise,会报:Vuex requires a Promise polyfill in this browser。
解决方法:1、npm install babel-polyfill --save
2、webpack.config.js中
使用

module.exports = {
entry: {
app: ["babel-polyfill", "./src/main.js"]
}
};

代替

module.exports = {
entry: {
app: './src/main.js'
}
}

更优雅的编程体验来啦~,像同步一样写异步代码。
5、async/await
6、Generator
最大的特点是交出函数的执行权,和普通的函数的区别是可以暂停执行,一般会在函数名之前加上* 以示区别
eg:下面是一个 Generator 函数

function* gen(x){
  var y = yield x + 2;
  return y;
}
var g = gen(1);
g.next() // { value: 3, done: false }
g.next() // { value: undefined, done: true }

ps:调用 Generator 函数,会返回一个内部指针g(即遍历器(iterator_es6:http://es6.ruanyifeng.com/#docs/iterator)),也就是说Generator 函数的执行后返回的是指针对象。每次调用指针对象的next方法,会返回一个对象,表示当前所处阶段的信息(value属性-是yield后的表达式的值,就是表示当前阶段的值和done属性-一个布尔值,表示Generator 函数是否执行完毕了)。
如何使用Generator函数??让我执行一个真实的异步任务吧~

三、区别优劣势-异步编程的优劣势,如何改变劣势


四、原理


五、一些疑问

1、js既是单线程又是异步的,这二者是否冲突,以及有什么区别-知乎

彩蛋

异步流程控制库:async,then.js,bluebird,Q,co


https://zhuanlan.zhihu.com/p/20322843
注:本文属于知识整理,侵权删

你可能感兴趣的:(JavaScript,Web前端)