We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
曾几何时,我们为了获取异步调用的结果,不得不大量使用回调函数,我们看下面这个例子:
通过Jquery的ajax获取服务器数据
let url1 = 'http://xxx.xxx.1'; $.ajax({ url:url1, error:function (error) {}, success:function (data1) { console.log(data1); } });
当需要发送多个异步请求,且每个请求之间需要相互依赖时,我们只能以嵌套的方式来解决
let url1 = 'http://xxx.xxx.1'; let url2 = 'http://xxx.xxx.2'; let url3 = 'http://xxx.xxx.3'; $.ajax({ url:url1, error:function (error) {}, success:function (data1) { console.log(data1); $.ajax({ url:url2, data:data1, error:function (error) {}, success:function (data2) { console.log(data2); $.ajax({ url:url3, data, error:function (error) {}, success:function (data3) { console.log(data3); } }); } }); } });
在处理多个异步逻辑时,就需要多层的回调函数嵌套,也就是我们常说的回调地狱。
这种编码模式的主要问题:
而Promise的出现,就是为了解决回调函数所引出的各种问题
Promise 是异步编程的一种解决方案,比传统的异步解决方案【回调函数】和【事件】更合理、更强大。
首先封装一个支持 Promise 的 ajax 方法,不理解这块代码的话,也没有关系,后文会逐步讲解 Promise 的执行机制
function request(url,data = {}){ return new Promise((resolve,reject)=>{ $.ajax({ url, data, success:function (data) { resolve(data); }, error:function (error) { reject(error); } }) }); }
用 request 方法实现前面多个互相依赖的网络请求
let url1 = 'http://xxx.xxx.1'; let url2 = 'http://xxx.xxx.2'; let url3 = 'http://xxx.xxx.3'; request(url1) .then((data)=>{ console.log(data); return request(url2,data) }) .then((data)=>{ console.log(data); return request(url3,data) }) .then((data)=>{ console.log(data) }) .catch((error)=>{ console.log(error); });
Promise 是一个构造函数,使用 new 操作符返回一个 promise 对象
构造函数接收一个 excutor 函数作为参数
excutor 函数有两个函数类型的参数 resolve 和 reject
let p = new Promise((resolve,reject)=>{ // 在 excutor 函数中执行异步操作 // 当异步操作完成后,调用 resolve 函数或 reject 函数 });
let p1 = new Promise((resolve,reject)=>{ setTimeout(()=>{ console.log('p1'); },1000); }); // p1 的状态一直为 pending
let p2 = new Promise((resolve,reject)=>{ setTimeout(()=>{ console.log('p2'); resolve('我是p2的终值') },1000); }); // 代码执行,1000ms内,p2 的状态为 pending // 代码执行,1000ms后,p2 的状态为 fulfilled // 代码执行,1000ms后,p2 的终值为 '我是p2的终值'
let p = new Promise((resolve,reject)=>{ reject('error') }) let p1 = new Promise((resolve,reject)=>{ resolve(p) }) // p1 的状态为 rejected ,拒因为 error
let thenable1 = { then:function(resolve,reject){ resolve(1) } } let thenable2 = { then:function(resolve,reject){ reject(2) } } let thenable3 = { then:function(resolve,reject){ throw new Error(3) } } let thenable4 = { then:function(fn1,fn2){ //不调用 fn1 fn2 } } let p1 = new Promise((resolve,reject)=>{ resolve(thenable1); }) let p2 = new Promise((resolve,reject)=>{ resolve(thenable2); }) let p3 = new Promise((resolve,reject)=>{ resolve(thenable3); }) let p4 = new Promise((resolve,reject)=>{ resolve(thenable4); }) // p1 的状态为 fulfilled 终值为 1 // p2 的状态为 rejected 终值为 2 // p3 的状态为 rejected 拒因为 Error:3 // p4 的状态为 pending
let p3 = new Promise((resolve,reject)=>{ setTimeout(()=>{ console.log('p3'); reject('我是p3的拒因') },1000); }); // 代码执行,1000ms内,p3 的状态为 pending // 代码执行,1000ms后,p3 的状态为 rejected // 代码执行,1000ms后,p3 的拒因为 '我是p3的拒因'
promise 提供一个 then 方法,用于访问其终值和拒因。
promise 的 then 方法接受两个参数:
promise.then(onFulfilled, onRejected);
new Promise((resolve,reject)=>{ setTimeout(()=>{ resolve('异步任务获取的数据') },50) }).then((data)=>{ console.log(data) }) // 异步任务获取的数据
new Promise((resolve,reject)=>{ setTimeout(()=>{ reject(new Error('异步任务异常')) },50) }).then(null,(error)=>{ console.log(error) }) // Error: 异步任务异常
new Promise((resolve,reject)=>{ throw new Error('抛出一个异常'); }).then(null,(error)=>{ console.log(error) }) // Error: 抛出一个异常
如果 onFulfilled 是函数:
如果 onRejected 是函数:
console.log(1); setTimeout(function(){ console.log(2) },0) new Promise((resolve,reject)=>{ resolve(3); }).then((data)=>{ console.log(data); }) console.log(4) // print: 1 4 3 2
function fn1(){ new Promise((resolve)=>{ resolve(); }).then(function(){ console.log(this) }) } function fn2(){ "use strict"; new Promise((resolve)=>{ resolve(); }).then(function(){ console.log(this) }) } fn1(); // print: window fn2(); // print: undefined
let p = new Promise((resolve)=>{ resolve() }); let p1 = p.then(()=>{ console.log('异步执行,第一个onFulfilled'); }); let p2 = p.then(()=>{ console.log('异步执行,第二个onFulfilled'); }); console.log(p1.constructor === Promise); console.log(p === p1); console.log(p === p2); console.log(p1 === p2); // print: true // print: false // print: false // print: false // print: 异步执行,第一个onFulfilled // print: 异步执行,第二个onFulfilled
then 方法返回一个 promise 对象
promise2 = promise1.then(onFulfilled, onRejected);
let p = new Promise((resolve,reject)=>{ throw new Error(); }); let p1 = p.then(null,(data)=>{ return '我是p2的终值' }); p1.then((data)=>{ console.log(data) }); // print: 我是p2的终值
let p1 = new Promise((resolve,reject)=>{ resolve(1) }) let p2 = new Promise((resolve,reject)=>{ reject(2) }) let p3 = new Promise((resolve)=>{ resolve() }) let p4 = p3.then(()=>{ return p1; }) let p5 = p3.then(()=>{ return p2; }) // p4 的状态为 fulfilled 终值为 1 // p5 的状态为 rejected 拒因为 2
let thenable1 = { then:function(resolve,reject){ resolve(1) } } let thenable2 = { then:function(resolve,reject){ reject(2) } } let p1 = new Promise((resolve,reject)=>{ resolve() }) let p2 = p1.then(()=>{ return thenable1; }) let p3 = p1.then(()=>{ return thenable2; }) // p2 的状态为 fulfilled 终值为 1 // p3 的状态为 rejected 拒因为 2
let p = new Promise((resolve,reject)=>{ resolve(); }); let p1 = p.then((data)=>{ throw new Error('error') }); p1.then(null,(err)=>{ console.log(err); }); // print: Error: error
let p = new Promise((resolve,reject)=>{ resolve('我是p1的终值'); }); let p1 = p.then(null,null); p1.then((data)=>{ console.log(data); }); // print: 我是p1的终值
let p = new Promise((resolve,reject)=>{ reject('我是p1的拒因'); }); let p1 = p.then(null,null); p1.then(null,(err)=>{ console.log(err); }); // print:我是p1的拒因
let p = new Promise((resolve,reject)=>{ resolve('我是p的终值'); }); let p1 = p.then((data)=>{ throw new Error('异常') }); p1.then(null,(err)=>{ console.log(err); }); // print:Error: 异常
let p1 = new Promise((resolve,reject)=>{ resolve(1) }) let p2 = new Promise((resolve,reject)=>{ reject(2) }) let p3 = p1.then(null,null); let p4 = p2.then(null,null); // p3 的状态是 fulfilled 终值 1 // p4 的状态是 rejected 拒因 2 p5 = p3.then(null,null); p6 = p4.then(null,null); // p3 的状态是 fulfilled 终值 1 // p4 的状态是 rejected 拒因 2
let fn1 = function(){} let fn2 = function(){} let fn3 = function(){} let fn4 = function(){} let fn5 = function(){} let onError = function(){}; new Promise((resolve,reject)=>{ setTimeout(function(){ reject() }) }) .then(fn1) .then(fn2) .then(fn3) .then(fn4) .then(fn5) .then(null,onError)
fn1、fn2、fn3、fn4、fn5 都可能发生错误,通过在最后的then函数注册的 onRejected 函数接收可能发生异常错误
catch(fn) 方法实际上是 then(null,fn) 方法的别名,catch 方法的返回值以及 catch 方法中出现异常的情况与调用 then 方法相同
new Promise((resolve,reject)=>{ reject() }).then(null,function(error){ }) // 等同于 new Promise((resolve,reject)=>{ reject() }).catch(function(error){ })
let p = Promise.resolve(x) // 等价于 let p = new Promise((resolve)=>{ resolve(x) })
let p = Promise.reject(x) // 等价于 let p = new Promise((resolve,reject)=>{ reject(x) })
const p = Promise.all([p1, p2, p3]);
let p1 = Promise.resolve(1); let p2 = Promise.resolve(2); let p3 = 3; Promise.all([p1,p2,p3]).then((data)=>{ console.log(data); // print: [1,2,3] })
let p1 = Promise.resolve(1); let p2 = new Promise((resolve,reject)=>{ setTimeout(function(){ reject('p2 error') },1000) }) let p3 = new Promise((resolve,reject)=>{ setTimeout(function(){ reject('p3 error') },500) }) Promise.all([p1,p2,p3]).catch((error)=>{ console.log(error); // print: p3 error })
const p = Promise.race([p1, p2, p3]);
let p1 = Promise.resolve(1); let p2 = new Promise((resolve,reject)=>{ setTimeout(function(){ reject('p2 error') },1000) }) let p3 = new Promise((resolve,reject)=>{ setTimeout(function(){ reject('p3 error') },500) }) Promise.race([p1,p2,p3]).then(data=>{ console.log(data); }).catch(error=>{ console.log(error); }) // print: 1
let p1 = new Promise((resolve,reject)=>{ setTimeout(function(){ resolve(1) },1000) }) let p2 = new Promise((resolve,reject)=>{ setTimeout(function(){ reject('p2 error') },800) }) let p3 = new Promise((resolve,reject)=>{ setTimeout(function(){ reject('p3 error') },500) }) Promise.race([p1,p2,p3]).then(data=>{ console.log(data); }).catch(error=>{ console.log(error); }) // print: p3 error
当 promise 的状态为 rejected 且为对 promise 对象使用 catch 方法,此时的异常信息会被 promise 对象吃掉 可以通过监听 unhandledRejection 事件,专门监听未捕获的reject错误
// node 环境下 process.on('unhandledRejection', error => { console.log('unhandledRejection', error); }); // 浏览器下 window.addEventListener('unhandledrejection',(e)=>{ e.preventDefault(); console.log(e); });
const promise = new Promise((resolve, reject) => { console.log(1) resolve() console.log(2) }) promise.then(() => { console.log(3) }) console.log(4)
结果:1 2 4 3
const promise = new Promise((resolve, reject) => { resolve('success1') reject('error') resolve('success2') }) promise .then((data) => { console.log(data) }) .catch((err) => { console.log(err) })
结果:success1
Promise.resolve(1) .then((data) => { console.log(data) return 2 }) .catch((err) => { return 3 }) .then((data) => { console.log(data) })
结果:1 2
Promise.resolve(1) .then(2) .then(Promise.resolve(3)) .then(console.log)
结果:1
new Promise((resolve,reject)=>{ console.log(3); let p = new Promise((resolve, reject)=>{ console.log(7); setTimeout(()=>{ console.log(5); resolve(6); },0) resolve(1); }); resolve(2); p.then((arg)=>{ console.log(arg); }); }).then((arg)=>{ console.log(arg); }); console.log(4);
结果:3 7 4 1 2 5
以上题目,如有疑问,可在留言区与我互动询问
点赞
关注
Watch
Star ★
欢迎关注微信公众号【前端小黑屋】,每周1-3篇精品优质文章推送,助你走上进阶之旅
【前端小黑屋】
The text was updated successfully, but these errors were encountered:
No branches or pull requests
Promise 出现的原因
曾几何时,我们为了获取异步调用的结果,不得不大量使用回调函数,我们看下面这个例子:
通过Jquery的ajax获取服务器数据
当需要发送多个异步请求,且每个请求之间需要相互依赖时,我们只能以嵌套的方式来解决
在处理多个异步逻辑时,就需要多层的回调函数嵌套,也就是我们常说的回调地狱。
这种编码模式的主要问题:
而Promise的出现,就是为了解决回调函数所引出的各种问题
什么是Promise
Promise 是异步编程的一种解决方案,比传统的异步解决方案【回调函数】和【事件】更合理、更强大。
代码书写比较
首先封装一个支持 Promise 的 ajax 方法,不理解这块代码的话,也没有关系,后文会逐步讲解 Promise 的执行机制
用 request 方法实现前面多个互相依赖的网络请求
Promise 的特性
promise 的状态
终值与拒因
状态与状态关系,状态与终值和拒因的关系
Promise 的使用
构造函数
Promise 是一个构造函数,使用 new 操作符返回一个 promise 对象
构造函数接收一个 excutor 函数作为参数
excutor 函数有两个函数类型的参数 resolve 和 reject
promise对象上的方法
then方法:
promise 提供一个 then 方法,用于访问其终值和拒因。
promise 的 then 方法接受两个参数:
onFulfilled 和 onRejected 参数可选
onFulfilled 特性
如果 onFulfilled 是函数:
onRejected 特性
如果 onRejected 是函数:
onFulfilled 和 onRejected 的调用时机
onFulfilled 和 onRejected 的调用要求
then方法的多次调用
then方法的返回值
then 方法返回一个 promise 对象
终值和拒因的穿透特性
fn1、fn2、fn3、fn4、fn5 都可能发生错误,通过在最后的then函数注册的 onRejected 函数接收可能发生异常错误
catch方法:
catch(fn) 方法实际上是 then(null,fn) 方法的别名,catch 方法的返回值以及 catch 方法中出现异常的情况与调用 then 方法相同
Promise 的静态方法
Promise.resolve
Promise.reject
Promise.all
Promise.race
Promise 的错误捕获
当 promise 的状态为 rejected 且为对 promise 对象使用 catch 方法,此时的异常信息会被 promise 对象吃掉
可以通过监听 unhandledRejection 事件,专门监听未捕获的reject错误
Promise 的问题
Promise 题目
题目一
结果:1 2 4 3
题目二
结果:success1
题目三
结果:1 2
题目四
结果:1
题目五
结果:3 7 4 1 2 5
以上题目,如有疑问,可在留言区与我互动询问
参考
写在最后
点赞
和关注
Watch
&Star ★
The text was updated successfully, but these errors were encountered: