new Promise()传进的参数是一个函数,会立即执行,可以注入两个参数,代表成功或失败的回调函数,setTimeout用来模拟请求的发送
// 创建一个pending状态的promise对象
const p = new Promise((resolved, rejected)=>{
setTimeout(function(){
// resolved(1000); // 异步操作成功时调用
rejected(new Error("出错了")); // 异步操作失败时调用
},1000)
})
console.log( p );
p.then(function(value){
console.log(value);
}, // 成功回调
function(err){
console.log(err); // 失败回调
})
// 创建一个已处理的promise对象
const p1 = Promise.resolve();
console.log( p1 );
// 创建一个已处理的promise对象(已失败)
const p2 = Promise.reject();
console.log( p2 )
仅有pending转resolved、pending转rejected两种可能
如果下一次请求需要前一次的数据,就需要在前一次调用的回调代码里写上这一次调用的代码,类似这样:
这样一层层嵌套下去,代码就显得很复杂,不好维护
then()返回的是一个promise对象,可以使用链式调用
规则:
then()的请求成功或失败,看的是return的是否为promise对象:
如果返回的是promise对象,则请求失败,执行失败的回调函数;
如果返回的不是promise对象,代表请求成功,执行成功的回调函数
举例:
返回的不是promise对象,即请求均成功:
const p = new Promise((resolved, rejected)=>{
setTimeout(function(){
resolved(1000); // 异步操作成功时调用
},1000)
})
// p.then返回的promise对象已不是原来的p
p.then(function(value){
// 记作f1
console.log(value); // 输出1000
return 111;
},
function(err){
// 记作f2
console.log(err);
})
.then(function(value){
// 记作f3
console.log(value); // 输出111
},
function(22){
// 记作f4
console.log(22);
})
异步操作p成功,执行f1,f1返回的不是一个promise对象,代表请求又成功了,就会调用f3,总体输出的是:1000 111
如果p失败,执行f2,由于没有return,默认代表是return undefined
,则第一个p.then请求成功,执行f3;f2没有return,f3没有接收到value,所以输出的是undefined
返回的是promise对象:
p成功,且第一个p.then在1s之后成功:
const p = new Promise((resolved, rejected) => {
setTimeout(function () {
resolved(1000); // 异步操作成功时调用
}, 1000)
})
p.then(function (value) {
// p成功后调用此处
console.log(value); // 输出1000
return new Promise((resolved, rejected)=>{
setTimeout(function () {
resolved(11);
}, 1000)})
}, // p.then成功
function (err) {
console.log(err);
})
.then(function (value) {
// 第一个p.then成功后调用此处
console.log(value); // 输出11
},
function () {
console.log(22);
})
p成功,但第一个p.then在1s之后失败:
const p = new Promise((resolved, rejected) => {
setTimeout(function () {
resolved(1000); // 异步操作成功时调用
}, 1000)
})
p.then(function (value) {
// p成功后调用此处
console.log(value); // 1000
return new Promise((resolved, rejected)=>{
setTimeout(function () {
rejected(); // 此处rejected,代表整个p.then失败
}, 1000)})
},
function (err) {
console.log(err);
})
.then(function (value) {
console.log(value);
},
function () {
//上一个p.then失败,调用此处
console.log(22); // 22
})
用链式调用代替回调金字塔
// 用链式调用解决回调金字塔
// 10s后打印10,再20s后打印20,再30s后打印30,打印的数字和等待的时间均由前一次请求指定
function fakeAjax(time, val) {
return new Promise((resolved, rejected) => {
setTimeout(function () {
resolved(val);
}, time)
})
}
fakeAjax(1000, 10).then((val) => {
console.log(val);
return fakeAjax(2000, 20);
},
() => {
}
)
.then((val) => {
console.log(val);
return fakeAjax(3000, 30)
},
() => {
})
.then((val) => {
console.log(val);
})
1.Promise.all :所有请求都成功时成功,其中一个失败,则整体失败
2.Promise.race:看响应最快的那个请求,如果成功,就执行成功的回调函数,失败,则整个失败,不再往后判断执行
Promise.all VS 完全成功:
function fakeAjax(time, val) {
return new Promise((resolved, rejected) => {
setTimeout(function () {
resolved(val);
}, time)
})
}
var p1 = fakeAjax(1000,10);
var p2 = fakeAjax(2000,20);
var p3 = fakeAjax(1500,30);
Promise.all([p1,p2,p3])
.then(function(val){
console.log(val); // 2s后输出[10, 20, 30]
},
function(err){
console.log(err);
})
Promise.all VS 其中一个不成功:
function fakeAjax(time, val, flag) {
return new Promise((resolved, rejected) => {
setTimeout(function () {
if (flag){
resolved(val);
}
else {
rejected(new Error("出错"))
}
}, time)
})
}
// flag为true时,成功
var p1 = fakeAjax(1000,10,true);
var p2 = fakeAjax(2000,20,true);
var p3 = fakeAjax(1500,30,false);
Promise.all([p1,p2,p3])
.then(function(val){
console.log(val);
},
function(err){
console.log(err); //打印错误信息
})
Promise.race VS 最快的请求是成功的
var p1 = fakeAjax(1000,10,true);
var p2 = fakeAjax(2000,20,true);
var p3 = fakeAjax(1500,30,false);
Promise.race([p1,p2,p3])
.then(function(val){
console.log(val); // 打印10
},
function(err){
console.log(err);
})
Promise.race VS 最快的请求是失败的:
var p1 = fakeAjax(1000,10,false);
var p2 = fakeAjax(2000,20,true);
var p3 = fakeAjax(1500,30,false);
Promise.race([p1,p2,p3])
.then(function(val){
console.log(val);
},
function(err){
console.log(err); //打印错误信息
})
catch()也代表失败回调函数,相当于then(null, ()=>{})