diff --git a/advanced/promise.md b/advanced/promise.md index 8a8dd506..39c44007 100644 --- a/advanced/promise.md +++ b/advanced/promise.md @@ -6,46 +6,36 @@ date: 2012-12-22 modifiedOn: 2013-11-28 --- -Promise是JavaScript异步操作解决方案。介绍Promise之前,先对异步操作做一个详细介绍。 +Promise 是 JavaScript 异步操作解决方案。介绍 Promise 之前,先对异步操作做一个详细介绍。 ## JavaScript的异步执行 ### 概述 -Javascript语言的执行环境是"单线程"(single thread)。所谓"单线程",就是指一次只能完成一件任务。如果有多个任务,就必须排队,前面一个任务完成,再执行后面一个任务。 +Javascript 语言的执行环境是“单线程”(single thread)。所谓“单线程”,就是指一次只能完成一件任务。如果有多个任务,就必须排队,前面一个任务完成,再执行后面一个任务。 -这种模式的好处是实现起来比较简单,执行环境相对单纯;坏处是只要有一个任务耗时很长,后面的任务都必须排队等着,会拖延整个程序的执行。常见的浏览器无响应(假死),往往就是因为某一段Javascript代码长时间运行(比如死循环),导致整个页面卡在这个地方,其他任务无法执行。 +这种模式的好处是实现起来比较简单,执行环境相对单纯;坏处是只要有一个任务耗时很长,后面的任务都必须排队等着,会拖延整个程序的执行。常见的浏览器无响应(假死),往往就是因为某一段 JavaScript 代码长时间运行(比如死循环),导致整个页面卡在这个地方,其他任务无法执行。 -JavaScript语言本身并不慢,慢的是读写外部数据,比如等待Ajax请求返回结果。这个时候,如果对方服务器迟迟没有响应,或者网络不通畅,就会导致脚本的长时间停滞。 +JavaScript 语言本身并不慢,慢的是读写外部数据,比如等待 Ajax 请求返回结果。这个时候,如果对方服务器迟迟没有响应,或者网络不通畅,就会导致脚本的长时间停滞。 -为了解决这个问题,Javascript语言将任务的执行模式分成两种:同步(Synchronous)和异步(Asynchronous)。"同步模式"就是传统做法,后一个任务等待前一个任务结束,然后再执行,程序的执行顺序与任务的排列顺序是一致的、同步的。这往往用于一些简单的、快速的、不涉及读写的操作。 +为了解决这个问题,Javascript 语言将任务的执行模式分成两种:同步(Synchronous)和异步(Asynchronous)。“同步模式”就是传统做法,后一个任务等待前一个任务结束,然后再执行,程序的执行顺序与任务的排列顺序是一致的、同步的。这往往用于一些简单的、快速的、不涉及 IO 读写的操作。 -"异步模式"则完全不同,每一个任务分成两段,第一段代码包含对外部数据的请求,第二段代码被写成一个回调函数,包含了对外部数据的处理。第一段代码执行完,不是立刻执行第二段代码,而是将程序的执行权交给第二个任务。等到外部数据返回了,再由系统通知执行第二段代码。所以,程序的执行顺序与任务的排列顺序是不一致的、异步的。 +“异步模式”则完全不同,每一个任务分成两段,第一段代码包含对外部数据的请求,第二段代码被写成一个回调函数,包含了对外部数据的处理。第一段代码执行完,不是立刻执行第二段代码,而是将程序的执行权交给第二个任务。等到外部数据返回了,再由系统通知执行第二段代码。所以,程序的执行顺序与任务的排列顺序是不一致的、异步的。 -以下总结了"异步模式"编程的几种方法,理解它们可以让你写出结构更合理、性能更出色、维护更方便的JavaScript程序。 +以下总结了"异步模式"编程的几种方法,理解它们可以让你写出结构更合理、性能更出色、维护更方便的 JavaScript 程序。 ### 回调函数 回调函数是异步编程最基本的方法。 -假定有两个函数f1和f2,后者等待前者的执行结果。 - -```javascript -f1(); -f2(); -``` - -上面代码中,`f2`必须要等到`f1`执行完,才能执行。 - -如果`f1`是一个很耗时的任务,可以考虑改写`f1`,把`f2`写成`f1`的回调函数。 +假定有两个函数`f1`和`f2`,后者必须等到前者执行完成,才能执行。这时,可以考虑改写`f1`,把`f2`写成`f1`的回调函数。 ```javascript function f1(callback) { - setTimeout(function () { - // f1的任务代码 - // ... - callback(); - }, 0); + // f1 的代码 + + // f1 执行完成后,调用回调函数 + callback(); } ``` @@ -55,8 +45,6 @@ function f1(callback) { f1(f2); ``` -采用这种方式,我们把同步操作变成了异步操作,`setTimeout(fn, 0)`将`fn`放到下一轮事件循环执行。`f1`不会堵塞程序运行,相当于先执行程序的主要逻辑,将耗时的操作推迟执行。 - 回调函数的优点是简单、容易理解和部署,缺点是不利于代码的阅读和维护,各个部分之间高度[耦合](http://en.wikipedia.org/wiki/Coupling_(computer_programming))(Coupling),使得程序结构混乱、流程难以追踪(尤其是回调函数嵌套的情况),而且每个任务只能指定一个回调函数。 ### 事件监听