回调函数真正的问题在于无法使用 return 和 throw 这些关键字。Promise 很好地解决了这一问题。
Promise是一个构造函数,自己身上有all、reject、resolve这几个方法,原型上有then、catch等同样方法。
缺点:
(1)无法取消 Promise,一旦新建它就会立即执行,无法中途取消。
(2)如果不设置回调函数,Promise 内部抛出的错误,不会反应到外部。
1.新建一个Promise
var p = new Promise(function(resolve, reject){
//异步操作
setTimeout(function(){
console.log('执行完成');
resolve('这里是数据');
}, 2000);
});
Promise的构造函数接收一个参数,是函数,并且传入两个参数:resolve,reject,分别表示异步操作执行成功后的回调函数和异步操作执行失败后的回调函数。
注意:这里只是new了一个对象,并没有调用它,我们传进去的函数就已经执行了,所以使用Promise的时候一般是包在一个函数中,在需要的时候去运行这个函数。
像这样:
function runAsync(){
var p = new Promise(function(resolve, reject){
//异步操作
setTimeout(function(){
console.log('执行完成');
resolve('这里是数据');
}, 2000);
});
return p;
}
runAsync()
2.串行执行若干异步任务
function runAsync1(){
var p = new Promise(function(resolve, reject){
//做一些异步操作
setTimeout(function(){
console.log('异步任务1执行完成');
resolve('随便什么数据1');
}, 1000);
});
return p;
}
function runAsync2(){
var p = new Promise(function(resolve, reject){
//做一些异步操作
setTimeout(function(){
console.log('异步任务2执行完成');
resolve('随便什么数据2');
}, 2000);
});
return p;
}
function runAsync3(){
var p = new Promise(function(resolve, reject){
//做一些异步操作
setTimeout(function(){
console.log('异步任务3执行完成');
resolve('随便什么数据3');
}, 2000);
});
return p;
}
runAsync1()//调用runAsync1
.then(function(data){
console.log(data); //打出随便什么数据1
return runAsync2(); //调用runAsync2
})
.then(function(data){
console.log(data); //打出随便什么数据2
return '直接返回数据'; //可以直接返回数据
})
.then(function(data){
console.log(data); //打出直接返回数据
});
结果是:
异步任务1执行完成
随便什么数据1
异步任务2执行完成
随便什么数据2
直接返回数据
3.并行执行异步任务
all()
var p1 = new Promise(function (resolve, reject) {
setTimeout(resolve, 500, 'P1');
});
var p2 = new Promise(function (resolve, reject) {
setTimeout(resolve, 600, 'P2');
});
// 同时执行p1和p2,并在它们都完成后执行then:
Promise.all([p1, p2]).then(function (results) {
console.log(results); // 获得一个Array: ['P1', 'P2']
});
race()
var p1 = new Promise(function (resolve, reject) {
setTimeout(resolve, 500, 'P1');
});
var p2 = new Promise(function (resolve, reject) {
setTimeout(resolve, 600, 'P2');
});
Promise.race([p1, p2]).then(function (result) {
console.log(result); // 'P1',获得先返回的结果
});
4.Promise ajax
// ajax函数将返回Promise对象:
function ajax(method, url, data) {
var request = new XMLHttpRequest();
return new Promise(function (resolve, reject) {
request.onreadystatechange = function () {
if (request.readyState === 4) {
if (request.status === 200) {
resolve(request.responseText);
} else {
reject(request.status);
}
}
};
request.open(method, url);
request.send(data);
});
}
var log = document.getElementById('test-promise-ajax-result');
var p = ajax('GET', '/api/categories');
p.then(function (text) { // 如果AJAX成功,获得响应内容
log.innerText = text;
}).catch(function (status) { // 如果AJAX失败,获得响应代码
log.innerText = 'ERROR: ' + status;
});
上边简单总结一下还有一些更细致的没有看完:
大白话讲解Promise(一):http://www.cnblogs.com/lvdabao/p/es6-promise-1.html
Javascript 中的神器——Promise:http://www.jianshu.com/p/063f7e490e9a
Promise 对象 阮一峰:http://es6.ruanyifeng.com/#docs/promise