You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
operation1(function(err,result){operation2(function(err,result){operation3(function(err,result){operation4(function(err,result){operation5(function(err,result){// do something useful})})})})})
varf1=function(callback){// do something here
...
callback.apply(this,para);};varf2=function(parameter){// do someting in customer callback};// call the fn with callback as parameterf1(f2);// 使用setTimeout()或者setInterval()也可以实现回调函数的异步调用functionf1(callback){setTimeout(function(){// f1的任务代码// ...callback();},0);}// 执行代码f1(f2);
Promise
什么是Promise?
Promise是一个对象,与其他的javascript对象的用法没什么不一样;Promise在异步编程中,主要起到代理作用,充当异步操作与回调函数之间的中介。它使得异步操作具备同步操作的接口,使得程序具备正常的同步运行的流程,回调函数不必再一层层嵌套。
Promise的思想,其实就是每一个异步任务立刻返回一个Promise对象,因为是立即返回的,所以可以采用同步操作的流程。
JavaScript的异步执行
javascript语言的执行环境是“单线程”的,也就是说javascript一次只能完成一个任务,如果有多个任务,就必须排队,前面一个任务完成了,下一个任务才能开始执行。
单线程模式实现起来比较简单,执行环境也相对单纯,但是如果有一个任务耗时很长,那么后面的任务就必须排队等候,这样整个程序的执行时间就会被拖长。这经常会造成浏览器无响应(假死),整个页面卡在某个地方,其他任务无法执行。
如果只有两三个可能的事件,单线程语言编写的面向事件的代码要比多线程代码简单很多,但是如果有很多事件,同时要求数据的状态能够从上一个事件传递到下一个事件,那么就会像下面代码那样,出现【回调地狱】:
javascript语言本身运行起来并不慢,慢的是读写外部数据,例如等待ajax请求返回的数据。为了解决这个问题,javascript语言将任务的执行模式分为:同步(Synchronous)和异步(Asynchronous)。
异步模式编程的几种常用方法是:回调函数、事件监听、发布/订阅
回调函数
如果函数f2需要等待f1的执行结果,并且f1是一个耗时很长的任务,那么可以考虑把f2写成f1的回调函数。
这样就把同步操作变成了异步操作,setTimeout(fn,0)将fn放到下一轮事件循环执行。f1不会堵塞程序运行,相当于先执行程序的主要逻辑,将耗时的操作推迟执行。
虽然回调函数简单、容易理解和部署,但是各部分耦合度高,程序结构混乱,回调函数嵌套的时候难以追踪流程,并且每一个任务只能指定一个回调函数。
事件监听
事件驱动模式——任务的执行不取决于代码的顺序,而取决于某个事件是否发生。例如:
事件监听可以绑定多个事件,每个事件可以指定多个回调函数,很好地解决了“耦合度高”的问题,但是这样子整个程序就会变成事件驱动,运行流程会变得很不清晰。
发布/订阅
发布/订阅模式,又称为观察者模式,如果把事件理解成“信号”,并且存在一个“信号中心”,某个任务执行完成后,就向信号中心publish一个信号,其他任务可以向信号中心订阅这个信号,从而知道什么时候自己可以开始执行。
这种方法我们可以通过查看“消息中心”,了解存在多少信号、每个信号的订阅情况,从而监控程序的运行。
创建promise对象
所以Promise的基本用法如下:
下面用Promise来通过异步处理方式来获取XMLHttpRequest(XHR)的数据
首先创建一个用Promise把XHR处理包装起来名为getURL的函数体
Promise对象实现Ajax操作的例子
Promise提供的各种方法
Promise.resolve
静态方法Promise.resolve(value)可以认为是new Promise()方法的快捷方式:
Promise.resolve方法的另一个作用就是将thenable对象转换为promise对象
thenable对象,是一个非常类似promise的东西,指的是一个具有.then方法的对象。最简单的thenable例子就是jQuery.ajax(),它的返回值就是thenable
将thenable对象转换为promise对象
resolve方法的参数除了正常的值以外,还可能是另一个Promise实例
Promise.reject
Promise.reject(error)是和Promise.resolve(value)类似的静态方法,是 new Promise()方法的快捷方式。
Promise.prototype.then方法:链式操作
因为Promise.prototype.then和 Promise.prototype.catch方法返回 promises对象, 所以它们可以被链式调用—— 一种被称为 composition 的操作。
.then有四种写法,各有差异:
Promise.prototype.catch方法:捕捉错误
实际上 Promise.prototype.catch 只是 promise.then(undefined, onRejected); 方法的一个别名而已。 也就是说,这个方法用来注册当promise对象状态变为Rejected时的回调函数。
Promise对象的错误具有“冒泡”性质,会一直向后传递,直到被捕获为止,也就是说,错误总会被下一个catch语句捕获。
Promise.all方法,Promise.race方法
Promise.all方法用于将多个Promise实例,包装成一个新的Promise实例
Promise.race方法同样是将多个Promise实例包装成一个新的Promise实例
Promise的应用
加载图片
Ajax操作
运用Ajax实现加载图片
参考文章 JavaScript Promise迷你书
The text was updated successfully, but these errors were encountered: