ES6:Promise详解

1、概念

Promise是JS中进行异步编程的新解决方案,相比回调函数和事件更合理和更强大。
从语法上来说:Promise是一个构造函数
从功能上说:Promise对象用来封装一个异步操作并可以获取其成功/失败的结果值

2、Promise有3种状态

  1. pending:初始状态也叫等待状态
  2. resolved:成功状态
  3. rejected:失败状态

状态一旦改变,就不会再变。创造promise实例后,它会立即执行。

3、Promise和async和await的区别

什么是async/await?
async/await 是ES7提出的基于Promise的解决异步的最终方案。
区别:
1 promise是ES6,async/await是ES7
2 async/await相对于promise来讲,写法更加优雅
3 reject状态:
1)promise错误可以通过catch来捕捉,建议尾部捕获错误,
2)async/await既可以用.then又可以用try-catch捕捉
一个函数如果加上 async ,那么该函数就会返回一个 Promise
async 和 await 可以说是异步终极解决方案了,相比直接使用 Promise 来说,优势在于处理 then 的调用链,能够更清晰准确的写出代码,毕竟写一大堆 then 也很恶心,并且也能优雅地解决回调地狱问题。当然也存在一些缺点,因为 await
将异步代码改造成了同步代码,如果多个异步代码没有依赖性却使用了 await 会导致性能上的降低。

4、Promise API

  1. Promise.resolve(value) 类方法,该方法返回一个以 value 值解析后的 Promise 对象
  • 如果这个值是个 thenable(即带有 then 方法),返回的 Promise 对象会“跟随”这个 thenable的对象,采用它的最终状态(指 resolved/rejected/pending/settled)
  • 如果传入的 value 本身就是 Promise 对象,则该对象作为 Promise.resolve 方法的返回值返回。
  • 其他情况以该值为成功状态返回一个 Promise对象。
  1. Promise.reject 类方法,且与 resolve 唯一的不同是,返回的 promise 对象的状态为 rejected。
  2. Promise.prototype.then 得到异步任务的正确结果
  3. Promise.prototype.catch 获取异常信息
  4. Promise.prototype.finally 成功或失败都会执行
  5. Promise.all() 接受Promise对象组成的数组作为参数,它的返回参数也是数组。当promise的全部为resolve后,它才会进入.then()方法,只要有一个promise为reject,它就会进入.catch()并发处理多个异步任务,所有任务都能执行完成才能得到结果。
  6. Promise.race() 接受的参数与Promise.all()一样,不同的是,它会辨别最快达到resolve或者reject的promise对象,如果这个最快是resolve,则进入.then()方法,如果是reject,则进入.catch()方法并发处理多个异步任务,只要有一个任务完成就能得到结果。

5、Promise是用来解决两个问题的:

★ 支持链式调用,可以解决回调地域问题
回调地狱:回调函数嵌套调用,外部回调函数异步执行的结果是嵌套的回调执行的条件
回调地狱缺点:不便于阅读;不便于异常处理
★ 指定回调函数的方式更加灵活

6、Promise的三个缺点

1)无法取消Promise,一旦新建它就会立即执行,无法中途取消
2)如果不设置回调函数,Promise内部抛出的错误,不会反映到外部
3)当处于pending(等待)状态时,无法得知目前进展到哪一个阶段,是刚刚开始还是即将完成

7、Promise的两个特点

1)Promise对象的状态不受外界影响
2)Promise的状态一旦改变,就不会再变,任何时候都可以得到这个结果,状态不可以逆

8、Promise异步调用实例

let p = new Promise((resolve, reject) => {
    
    
    setTimeout(() => {
    
    
    	resolve('OK');
    }, 1000);
});

p.then(value => {
    
    
    console.log(111);
    //有且只有一个方式(返回一个pending状态的Promise对象)
    return new Promise(() => {
    
    });
}).then(value => {
    
    
	console.log(222);
}).then(value => {
    
    
	console.log(333);
}).catch(reason => {
    
    
	console.warn(reason);
});

9、Promise、async、await执行顺序

async function async1(){
    
    
	console.log('async1 start')	//2  
    // 执行async2函数的 setTimeout
    await async2()
    setTimeout(function(){
    
    
        // 等上面执行完在执行
        console.log('setTimeout1')//8
	},0)
}		
async function async2(){
    
    
    setTimeout(function(){
    
    
    	console.log('setTimeout2')//7
    },0)
}
console.log('script start')//1    //执行同步代码
setTimeout(function(){
    
    
    // 最后执行setTimeout
    console.log('setTimeout3')//6
},0)
async1()  			//调用 
//执行先执行同步 输出2

// 调用
// 执行异步setTimeout
new Promise(function(r,j){
    
    
	console.log('Promise1')//3  //按照代码顺序
	r()
}).then(function(){
    
    
    // 等主线任务完成在执行
    console.log('Promise2')//5
})
console.log('script end')//4

10、Promise实例

console.log("start");

setTimeout(()=>{
    
    
	console.log("setTimeout");
},0);
    
new Promise((resolve,reject)=>{
    
    
	for(var i=0;i<5;i++){
    
    
    	console.log(i);
    }
    resolve() //修改promise状态为成功
}).then(()=>{
    
    
    console.log("promise回调函数");
})

console.log("end");
第一个宏任务队列
执行主线程上的代码
第二个宏任务
setTimeout
微任务队列
new Promise.then()
1、先执行主线程上的同步代码,输出start
2、遇到setTimeout将其加入到宏任务队列等待执行
3、遇到promise 立即执行,输出 01234
4、遇到promise的回调函数将其加入到微任务队列
5、执行主线程的同步代码,输出end
6、第一个宏任务队列执行完毕查看存在微任务队列,执行微任务队列中的任务,输出promise的回调函数
7、微任务执行完毕,执行下一个宏任务队列中的任务,输出setTimeout
输出:
start
0
1
2
3
4
end
promise回调函数
setTimeout

猜你喜欢

转载自blog.csdn.net/DZQ1223/article/details/131422587
今日推荐