javascript语言是一门“单线程”的语言,不像java语言,类继承Thread再来个thread.start就能够开辟一个线程,因此,javascript就像一条流水线,仅仅是一条流水线而已,要么加工,要么包装,不能同时进行多个任务和流程。javascript
因此同步和异步,不管如何,作事情的时候都是只有一条流水线(单线程),同步和异步的差异就在于这条流水线上各个流程的执行顺序不一样。java
一、最基础的异步是setTimeout和setInterval函数,很常见,可是不多人有人知道其实这就是异步,由于它们能够控制js的执行顺序。咱们也能够简单地理解为:能够改变程序正ajax
常执行顺序的操做就能够当作是异步操做promise
1 <script type="text/javascript"> 2 console.log( "1" ); 3 setTimeout(function() { 4 console.log( "2" ) 5 }, 0 ); 6 setTimeout(function() { 7 console.log( "3" ) 8 }, 0 ); 9 setTimeout(function() { 10 console.log( "4" ) 11 }, 0 ); 12 console.log( "5" ); 13 </script>
输出顺序:浏览器
在执行程序的时候,浏览器会默认setTimeout以及ajax请求这一类的方法都是耗时程序(尽管可能不耗时),将其加入一个队列中,该队列是一个存储耗时程序的队列,网络
在全部不耗时程序执行事后,再来依次执行该队列中的程序。异步
二、又回到了最初的起点——javascript是单线程。单线程就意味着,全部任务须要排队,前一个任务结束,才会执行后一个任务。若是前一个任务耗时很长,后一个任务就不async
得不一直等着。因而就有一个概念——任务队列。若是排队是由于计算量大,CPU忙不过来,倒也算了,可是不少时候CPU是闲着的,由于IO设备(输入输出设备)很函数
慢(好比Ajax操做从网络读取数据),不得不等着结果出来,再往下执行。因而JavaScript语言的设计者意识到,这时主线程彻底能够无论IO设备,挂起处于等待中的任spa
务,先运行排在后面的任务。等到IO设备返回告终果,再回过头,把挂起的任务继续执行下去。
因而,全部任务能够分红两种,一种是同步任务(synchronous),另外一种是异步任务(asynchronous)。同步任务指的是,在主线程上排队执行的任务,只有前一个任务
执行完毕,才能执行后一个任务;异步任务指的是,不进入主线程、而进入"任务队列"(task queue)的任务,只有等主线程任务执行完毕,"任务队列"开始通知主线程,
请求执行任务,该任务才会进入主线程执行。
Promise
的真正强大之处在于它的多重链式调用,能够避免层层嵌套回调
Promise
对象表明一个未完成、但预计未来会完成的操做。
它有如下三种状态:
pending
:初始值,不是fulfilled,也不是rejectedfulfilled
:表明操做成功rejected
:表明操做失败/* 例3.1 */ //构建Promise var promise = new Promise(function (resolve, reject) { if (/* 异步操做成功 */) { resolve(data); } else { /* 异步操做失败 */ reject(error); } });
相似构建对象,咱们使用new
来构建一个Promise
。Promise
接受一个「函数」做为参数,该函数的两个参数分别是resolve
和reject
。这两个函数就是就是「回调函数」,由JavaScript引擎提供。
resolve
函数的做用:在异步操做成功时调用,并将异步操做的结果,做为参数传递出去; reject
函数的做用:在异步操做失败时调用,并将异步操做报出的错误,做为参数传递出去。
Promise实例生成之后,能够用then
方法指定resolved
状态和reject
状态的回调函数。
/* 接例3.1 */ promise.then(onFulfilled, onRejected); promise.then(function(data) { // do something when success }, function(error) { // do something when failure });
then
方法会返回一个Promise。它有两个参数,分别为Promise从pending
变为fulfilled
和rejected
时的回调函数(第二个参数非必选)。这两个函数都接受Promise对象传出的值做为参数。
简单来讲,then
就是定义resolve
和reject
函数的,其resolve
参数至关于:
function resolveFun(data) { //data为promise传出的值 }
而新建Promise中的'resolve(data)',则至关于执行resolveFun函数。
Promise新建后就会当即执行。而then
方法中指定的回调函数,将在当前脚本全部同步任务执行完才会执行。