一、js的异步机制
JS是单线程的语言,执行任务包括同步任务和异步任务。
同步任务:在主线程上排队执行的任务,形成执行栈
异步任务:不进入主线程、而进入"任务队列"(task queue)的任务.
只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。
只要主线程空了,就会去读取"任务队列",其实就是读取事件。执行相应的回调函数。这就是JavaScript的运行机制
"任务队列"是一个先进先出的数据结构,排在前面的事件,优先被主线程读取。
异步实现的核心是回调函数
常见 的异步操作:
1.网络请求:http请求
2.I/O操作:读取文件
3.定时器:setTimeout、setInterval。间隔时间后,加入任务队列,等待主线程的提取,执行。
注意:setTimeout(fn,0)的含义是,指定某个任务在主线程最早可得的空闲时间执行,也就是说,尽可能早
得执行。它在"任务队列"的尾部添加一个事件,因此要等到同步任务和"任务队列"现有的事件都处理完,
才会得到执行。
二、promise对象
promise有三种状态:pending、fullfilled、reject。
Promise对象:是一个构造函数,用于生成promise实例。
保存着未来才会结束的事件(通常是异步操作)的结果。从它可以获取异步操作的消息。
基本用法
var promise = new Promise(function(resolve, reject) {
// ... some code
if (/* 异步操作成功 */){
resolve(value);
} else {
reject(error);
}
});
Promise
构造函数接受一个函数作为参数,该函数的两个参数分别是resolve
和reject
。它们是两个函数,由 JavaScript 引擎提供,不用自己部署。
三、promise对象的原型方法
1. then(),第一个参数为resolved状态的回调函数,第二个状态为rejected状态的回调函数。
then返回一个新的promise实例,因此可以采用链式调用,第一个回调函数完成以后,会将结果作
为 参数传入第二个回调函数。
采用链式的then
,可以指定一组按照次序调用的回调函数
2. catch()指定发生错误时的回调函数。
如果异步操作抛出错误,状态就会变为rejected
,就会调用catch
方法指定的回调函数,处理这个 错误。
另外,then
方法指定的回调函数,如果运行中抛出错误,也会被catch
方法捕获。
错误总是会被下一个cantch语句捕获。
一般情况下,不在then中指定rejected状态的回调函数,而是使用catch语句。
般总是建议,Promise 对象后面要跟catch
方法,这样可以处理 Promise 内部发生的错误。catch
方 法返回的还是一个 Promise 对象,因此后面还可以接着调用then
方法。
3.done:位于回调链的尾端,保证抛出任何可能出现的错误
4. finally():不管Promise对象最后状态如何,都会执行的操作。它接受一个普通的回调函数作为参数,该函
数 不管怎样都必须执行。
四、实例方法
1. Promise.
all():Promise.all
方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。
Promise.all
方法的参数可以不是数组,但必须具有 Iterator 接口,且返回的每个成员都是
Promise 实例
只要p的状态都为resolved,p才为resolved。。p1
、p2
、p3
的返回值组成一个数组,传递给p
的回调函 数。
只要p1
、p2
、p3
之中有一个被rejected
,p
的状态就变成rejected
,此时第一个被reject
的实例的返回 值,会传递给p
的回调函数。
注意,如果作为参数的 Promise 实例,自己定义了catch
方法,那么它一旦被rejected
,并不会触发
Promise.all()
的catch
方法。
2. Promise.race():用于将多个 Promise 实例,包装成一个新的 Promise 实例。
只要p1
、p2
、p3
之中有一个实例率先改变状态,p
的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p
的回调函数.只要有一个为resolved,就为resolved。
Promise.race
方法的参数与Promise.all
方法一样,如果不是 Promise 实例,就会先调用
Promise.resolve
方法,将参数转为 Promise 实例,再进一步处理。
3. Promise. resolve() :将现有对象,转换为resolved状态的promise对象
1。参数为promise实例
2.参数为thenable对象
3.参数不是thenable对象,甚至不是对象。如果参数是一个原始值,或者是一个不具有then
方法的对象,则Promise.resolve
方法返回一个新的Promise对象,状态为resolved
。
4.无参数。直接返回一个resolved
状态的Promise对象。立即resolve
的Promise对象,是在
本轮“事件循环”(event loop)的结束时,而不是在下一轮“事件循环”的开始时。
4. Promise. reject() :将现有对象,转换为rejected状态的promise对象。
注意:Promise.reject()
方法的参数,会原封不动地作为reject的参数
,变成后续方法的参数。这
一点与Promise.resolve
方法不一致。
5. Promise. try() : 包装后,异步操作就会异步执行,同步操作就会同步执行。