Promise是ES6引入的一个新的语法,专门用于异步编程。
在js中,异步编程有三种
setInterval(() => {// ...
}, interval);
setTimeout(() => {// ...
}, timeout);
$.ajax({url,data,success:function (result){alert(result)}
})
//定义主函数,回调函数作为参数
function A(callback) {callback();console.log('我是主函数');
}//定义回调函数
function B() {setTimeout("console.log('我是回调函数')",2000);//即使此时时间设置为0,也会先输出主函数
}//调用主函数,将B传进去
A(B);
① 多次异步调用的结果顺序不确定
② 异步调用结果如果存在依赖必须使用嵌套
Promise是异步编程的一种解决方案,从语法上讲,Promise是一个对象,它可以获取异步操作的消息
官方:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
① 可以避免多层异步调用嵌套问题(回调函数)
② Promise 对象提供了简洁的API,使得控制异步操作更加容易
实例化Promise对象,构造函数中传递函数,该函数中用于处理异步任务
new Promise(function(resolve, reject){ })
resolve和reject两个参数用于处理成功和失败两种情况
如果想让Promise成功执行下去,需要执行resolve,如果让它失败执行下去,需要执行reject
resolve进then,reject进catch
var p = new Promise(function(resolve,reject){// 这里用于实现异步任务// 成功时调用resolve()// 失败时调用reject()
});
p.then(function (data) {// 从resolve得到正常结果console.log(data);
}).catch( function (info) {// 从reject得到错误信息console.log(info);
})
var p = new Promise(function (resolve, reject) {setTimeout(function () {var flag = false;if (flag) {//正常情况下resolve("hello");} else {reject("出错了");}}, 1000);
});
// 方法一
p.then(function (data) {console.log(data);}).catch( function (info) {console.log(info);})
// 方法二
p.then(function (data) {console.log(data);},function (info) {console.log(info);})// 方法一和方法二等效
如果想终止在某个执行链的位置,可以用Promise.reject(new Error())
new Promise(function(resolve, reject) {resolve(1)
}).then(result => {return result + 1
}).then(result => {return result + 1
}).then(result => {// 终止掉程序,不再进入下一个then而是进入catchreturn Promise.reject(new Error(result + '失败'))// return result + 1
}).then(result => {return result + 1
}).catch(error => { alert(error)
})
封装Promise函数
function queryData() {return new Promise(function (resolve, reject) {var xhr = new XMLHttpRequest();xhr.onreadystatechange = function () {if (xhr.readyState != 4) return; //不做处理if (xhr.status == 200) {//处理正常的情况resolve(xhr, responseText);} else {//处理异常的情况reject("出错了");}};xhr.open("get", "/data");xhr.send(null);});
}
① 返回Promise实例对象
返回的该实例对象会调用下一个then
queryData("http://localhost:3000/data").then(function (data) {console.log(data);}).catch(function (info) {console.log(info);});
② 返回普通值
返回的普通值会直接传递给下一个then,通过then参数中函数的参数接收该值
//发送多个ajax请求并且保证顺序
queryData("http://localhost:3000/data").then(function (data) {console.log(data);return qureyData("http://localhost:3000/data1");}).then(function (data) {console.log(data);return qureyData("http://localhost:3000/data2");}).then(function (data) {console.log(data);});
原型中的方法
| 方法 | 说明 |
|---|---|
| .then() | 得到异步执行任务的正确结果 |
| .catch() | 获取异常信息 |
| .finally() | 成功与否都会执行 |
queryData().then(function (data) {console.log(data);}).catch(function (info) {console.log(info);}).finally(function (info) {console.log(info);})
| 方法 | 说明 |
|---|---|
| Promise.all() | 并发处理多个异步任务,所有任务都执行完成才能得到结果 |
| Promise.race() | 并发处理多个异步任务,只要有一个任务完成就得到结果 |
Promise.all([p1,p2,p3]).then(result=>{console.log(result);
})Promise.race([p1,p2,p3]).then(result=>{console.log(result);
})