es6中有个特别的对象Promise,今天我们就来学习它,了解它。
Promise含义
Promise 是异步编程的一种解决方案,过往遇到异步编程的时候都是采用回调函数或者事件的形式,它的出现让异步编程更加合理和强大。
Promise用法
通过ES6,Promise对象是一个构造函数,用来生成Promise实例
用最有代表的ajax实现异步。
var promise = new Promise(function(resolve, reject) {
// ... some code
$.ajax({
url: url,
dataType: 'json',
success: function (data) {
resolve(data)
},
error:function(err){
reject()
}
})
});
promise.then(function(value) {
// success
}, function(error) {
// failure
});
这就是基本的用法。
特点
- 对象的状态不受外界影响
- 一旦状态改变,就不会再变,任何时候都可以得到这个结果
Promise的三种状态
- pending(进行中)
- resolved(已完成,又称 Fulfilled)
- Rejected(已失败)
在上面Promise构造函数接受一个函数作为参数,这个函数有两个参数,
resolve()函数是将Promise的状态从“未完成”变为“成功”,并将结果作为参数传递给回调的函数,
reject()函数是将Promise的状态从“未完成”变为“失败”。
Promise实例生成以后,then
方法分别指定Resolved状态和Reject状态的回调函数。
例子1:
var p = new Promise(function (resolve, reject) {
setTimeout(function () {
resolve('owen');
}, 1000);
});
p.then(function(val){
console.log(val)//一秒后打印owen
})
例子2:
var p = new Promise(function (resolve, reject) {
setTimeout(function () {
resolve('owen');
}, 1000);
});
p.then(function(val){
console.log(val)//一秒后打印owen
return 'obj'
}).then(function(str){
setTimeout(function() {
console.log(str)//两秒后打印obj
}, 1000);
})
我们可以发现,第二个then在第一个then结束后执行,并且接受了第一个then的返回值。
那结论是:每个then中的回调函数都是接受上一个函数的返回值作为参数传递下去。
例子3:
var ajaxPromise = new Promise(function (resolve) {
resolve(resolve)
});
ajaxPromise.then(function () {
var p = new Promise(function (resolve, reject) {
$.ajax({
url: url,
dataType: 'json',
success: function (data) {
id = data.data[0].id;
resolve(id)
}
})
});
//返回一个Promise对象
return p;
}).then(function (id) {
console.log(id);
$.ajax({
url: url + id,
dataType: 'json',
success: function (data) {
console.log(data);
}
})
})
这是一种情况后面的回调函数依赖前一个回调函数的某个数据。
首先创建一个promise实例,立即执行回调,第一个回调执行后获取id,提供个第二个回调使用。由于这里是ajax获取id,属于异步操作,使用return id
第二个回调函数必然拿不到id,所以这里重新创建promise实例,并且返回promise实例。
Promise.prototype.catch()
var Promise = new Promise(function (resolve,reject) {
reject('1')
});
Promise.then(function(val){
console.log(val)
}).catch(function(err){
console.log(err)
})
catch()是指定发生错误时的回调函数。我们调用reject() 使promise状态变改为失败,抛出错误,触发catch()方法,当然then()方法指定的回调如果异步操作抛出错误,一样会触发catch()
var Promise = new Promise(function (resolve,reject) {
resolve('1')
});
Promise.then(function(val){
throw new Error('errs');
}).then(function(val){
console.log(2)
}).catch(function(err){
console.log(err)//只会执行这里
})
注意点:
var promise = new Promise(function(resolve, reject) {
resolve('ok');
throw new Error('test');
});
promise
.then(function(value) { console.log(value) })//只会执行这里 ok
.catch(function(error) { console.log(error) });
因为当执行resolve()后promise状态已经被改为成功,且不会再被改变。
Promise.all()
Promise.all方法接受一个数组(伪数组)作为参数。
var p1=new Promise(function(resolve,reject){
$.ajax({
url: url,
dataType: 'json',
success: function (data) {
id = data.data[0].id;
resolve(id)
}
})
})
var p2=new Promise(function(resolve,reject){
$.ajax({
url: url,
dataType: 'json',
success: function (data) {
cid = data.data[0].cid;
resolve(cid)
}
})
})
var p=Promise.all([p1,p2]).then(function(val){
console.log(val) //返回一个数组
})
all()规定参数必须为promise对象。它返回的时间取决于耗时最长操作,且p的状态取决于p1,p2。
- p1,p2都变为fulfilled时候,p的状态变为fulfilled
- 只要有一项为rejected,p的状态变为rejected
试想一下使用场景:某一个操作需要的多个数据来源于其他的多个异步操作,这时我们就可以使用all().
Promise.race()
用法跟Promise.all()一样,不同点:
- p的状态取决于p1,p2 哪个先执行完
Promise.resolve()
将现有对象转为Promise对象
var obj={
a:1
}
var p1=Promise.resolve(obj)
//等价于
var p2=new Promise(function(resolve,reject){
resolve(obj)
})
网友评论