异步调用
- 定时任务(setTimeout、setInterval)
- ajax
- 事件处理函数
Promise
一个 Promise 对象代表一个在这个 promise 被创建出来时不一定已知的值。它让您能够把异步操作最终的成功返回值或者失败原因和相应的处理程序关联起来。 这样使得异步方法可以像同步方法那样返回值:异步方法并不会立即返回最终的值,而是会返回一个 promise,以便在未来某个时候把值交给使用者
Promise 对象用于表示一个异步操作的最终完成 (或失败)及其结果值,解决异步编程的一种方案,可以避免多层异步调用嵌套问题(回调地狱)
Promise对象提供了简洁API使得控制异步操作更容易
基本使用
一个 Promise 必然处于以下几种状态之一:
- 待定(pending): 初始状态,既没有被兑现,也没有被拒绝。
- 已兑现(fulfilled): 意味着操作成功完成。
- 已拒绝(rejected): 意味着操作失败。
实例化 Promise 对象,构造函数中传递函数,
该函数中用于处理异步任务resolve 和 reject 两个参数用于处理成功和失败两种情况,并通过 p.then 获取处理结果
var p = new Promise(function(resolve, reject){
// 成功时调用 resolve()
// 失败时调用 reject()
});
p.then(funciton(ret){
// 从resolve得到正常结果
}, function(ret){
// 从reject得到错误信息
});
then中的参数的函数返回值
- 返回Promise实例对象
返回的实例对象会调用下一个then
- 返回普通值
返回的普通值会直接传递给下一个then,通过then参数中函数的参数接收该值
//示例代码
<script>
//封装一个函数
function quertData(url) {
var p = new Promise(function (resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.open("get", url);
xhr.send(null);
xhr.onreadystatechange = function () {
if (xhr.readyState != 4) return;
if (xhr.readyState == 4 && xhr.status == 200) {
resolve(xhr.responseText);
} else {
reject("服务器出错");
}
};
});
return p;
}
quertData("http://127.0.0.1:80/data")
.then(function (data) {
return quertData("http://127.0.0.1:80/data");
})
.then(function (data) {
console.log(data);
return "133";
})
.then(function (data) {
console.log(data);
});
</script>
Promise常用API
实例方法
- p.then() 得到异步任务的正确结果
- p.catch() 获取异常信息
- p.finally() 成功与否都会执行(尚且不是正式标准)
对象方法
- Promise.all() 并发处理多个异步任务,所有任务都执行完成才能得到结果
- Promise.race() 并发处理多个任务,只要有一个任务完成就能得到结果
Promise的链式调用
解决回调地狱问题
我们可以用 promise.then(),promise.catch() 和 promise.finally() 这些方法将进一步的操作与一个变为已敲定状态的 promise 关联起来。这些方法还会返回一个新生成的 promise 对象,这个对象可以被非强制性的用来做链式调用
const myPromise =
(new Promise(myExecutorFunc))
.then(handleFulfilledA,handleRejectedA)
.then(handleFulfilledB,handleRejectedB)
.then(handleFulfilledC,handleRejectedC);
// 或者,这样可能会更好...
const myPromise =
(new Promise(myExecutorFunc))
.then(handleFulfilledA)
.then(handleFulfilledB)
.then(handleFulfilledC)
.catch(handleRejectedAny);
<script type="text/javascript">
/*
then参数中的函数返回值
*/
function queryData(url) {
return new Promise(function(resolve, reject){
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if(xhr.readyState != 4) return;
if(xhr.readyState == 4 && xhr.status == 200) {
// 处理正常的情况
resolve(xhr.responseText);
}else{
// 处理异常情况
reject('服务器错误');
}
};
xhr.open('get', url);
xhr.send(null);
});
}
queryData('http://localhost:3000/data')
.then(function(data){
return queryData('http://localhost:3000/data1');
})
.then(function(data){
return new Promise(function(resolve, reject){
setTimeout(function(){
resolve(123);
},1000)
});
})
.then(function(data){
return 'hello';
})
.then(function(data){
console.log(data)
})
</script>