五、Promise
1、认识Promise
Promise到底是做什么的呢?
Promise是ES6中一个非常重要和好用的特性,是异步编程的一种解决方案。
我们来考虑下面的场景(有夸张的成分):
- 我们需要通过一个url1从服务器加载一个数据data1,data1中包含了下一个请求的url2
- 我们需要通过data1取出url2,从服务器加载数据data2,data2中包含了下一个请求的url3
- 我们需要通过data2取出url3,从服务器加载数据data3,data3中包含了下一个请求的url4
- 发送网络请求url4,获取最终的数据data4
上面的代码有什么问题吗?不够优雅!Promise可以以一种非常优雅的方式来解决这个问题。
2、Promise的使用
01-Promise的基本使用
这里,我们用一个定时器来模拟异步事件。
假设下面的result是从网络上1秒后请求的结果,根据结果的不同我们采取不同额处理方式
new Promise((resolve, reject) => { setTimeout(function () { let result = false; if (result == true) { resolve("网络数据返回数据为true"); } else { reject("网络数据返回为false"); } }, 1000); }) .then((data) => { console.log(data); }) .catch((data) => { console.log(data); });
02-Promise三种状态
异步操作之后会有三种状态
- pending:等待状态,比如正在进行网络请求,或者定时器没有到时间。
- fulfill:满足状态,当我们主动回调了resolve时,就处于该状态,并且会回调.then()
- reject:拒绝状态,当我们主动回调了reject时,就处于该状态,并且会回调.catch()
03-Promise的另外处理形式
04-Promise的处理多次回调形式
/* 我们需要通过一个url1从服务器加载一个数据data1,data1中包含了下一个请求的url2 我们需要通过data1取出url2,从服务器加载数据data2,data2中包含了下一个请求的url3 我们需要通过data2取出url3,从服务器加载数据data3,data3中包含了下一个请求的url4 发送网络请求url4,获取最终的数据data4 */ new Promise((resolve, reject) => { setTimeout(function () { let data1 = { url2: "www.baidu.com", msg: "通过一个url1从服务器加载一个数据data1", }; resolve(data1); }, 1000); }).then( (data) => { console.log("我们通过data1取出url2: " + data.url2); new Promise((resolve, reject) => { setTimeout(function () { let data2 = { url3: "www.qq.com", }; resolve(data2); }, 1000); }).then( (data) => { console.log("我们通过data2取出url3: " + data.url3); new Promise((resolve, reject) => { setTimeout(function () { let data3 = { url4: "www.cnblogs.com", }; resolve(data3); }, 1000); }).then((data) => { console.log("我们通过data3取出url4: " + data.url4); new Promise((resolve, reject) => { setTimeout(function () { let data4 = { msg: "我是data4中的数据", }; resolve(data4); }, 1000); }).then((data) => { console.log(data.msg); }); }); } ); }, (error) => { console.log(error); } );
/* 我们需要通过一个url1从服务器加载一个数据data1,data1中包含了下一个请求的url2 我们需要通过data1取出url2,从服务器加载数据data2,data2中包含了下一个请求的url3 我们需要通过data2取出url3,从服务器加载数据data3,data3中包含了下一个请求的url4 发送网络请求url4,获取最终的数据data4 */ new Promise((resolve, reject) => { setTimeout(function () { let data1 = { url2: "www.baidu.com", msg: "通过一个url1从服务器加载一个数据data1", }; resolve(data1); }, 1000); }) .then( (data) => { console.log("我们通过data1取出url2: " + data.url2); return new Promise((resolve, reject) => { setTimeout(function () { let data2 = { url3: "www.qq.com", }; resolve(data2); }, 1000); }); }, (error) => { console.log(error); } ) .then((data) => { console.log("我们通过data2取出url3: " + data.url3); return new Promise((resolve, reject) => { setTimeout(function () { let data3 = { url4: "www.cnblogs.com", }; resolve(data3); }, 1000); }); }) .then((data) => { console.log("我们通过data3取出url4: " + data.url4); let data4 = { msg: "我是data4中的数据", }; return Promise.resolve(data4); }) .then((data) => { console.log(data.msg); });
3.0 版本的简写
05-Promise的all方法使用
Promise.all([ new Promise((resolve, reject) => { setTimeout(function () { resolve({name:"yango",age:20}); }, 2000); }), new Promise((resolve, reject) => { setTimeout(function () { resolve({name:"yangke",age:21}); }, 1000); }), ]).then(results=>{ console.log(results); });