什么是Promise
Promise 是异步编程的一种解决方案,比传统的异步解决方案【回调函数】和【事件】更合理、更强大。现已被 ES6 纳入进规范中。也可说Promise对象用于表示一个异步操作的最终状态(成功或失败)以及其返回的值。 (同步与异步:同步任务会阻塞程序执行,异步不会)
Promise 的三种状态
- 对象的状态不受外界影响,Promise对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败),只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态,这也是Promise这个名字的由来,它的英语意思就是“承诺”,表示其他手段无法改变。
- 一旦状态改变,就不会再变,任何时候都可以得到这个结果,Promise对象的状态改变,只有两种可能:从pending变为fulfilled和从pending变为rejected,只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果,这时就称为 resolved(已定型),如果改变已经发生了,你再对Promise对象添加回调函数,也会立即得到这个结果,这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。
- Promise对象优点,可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数
Promise 的常用 API
Promise.all()
- Promise.all方法可以把多个promise实例,包装成一个新的promise实例。
- Promise.all([ promise1, promise2 ]) : Promise。all()方法接收一个数组(两个Promise实例)作为参数,最终返回一个Promise实例。
- 决议的3中情况:promise1, promise2都决议成功,则Promise.all决议成功,1和2实例返回的参数以数组的形式按顺序传递出去;如果1和2中有一个失败,则最终决议为失败,并将失败的结果传递出去;如果没有1和2,all参数为空,则最终决议成功。
- 例:模拟需要多个请求的数据 才能进行下一步操作的情况
function getData1() {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('第一条数据加载成功');
resolve('data1');
}, 1000);
});
}
function getData2() {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('第二条数据加载成功');
resolve('data2');
}, 1000);
});
}
function getData3() {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('第三条数据加载成功');
resolve('data3');
}, 1000);
});
}
function getData4() {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('第四条数据加载成功');
resolve('data4');
}, 2000);
});
}
let p = Promise.all([getData1(), getData2(), getData3(), getData4()]);
p.then(arr => {
console.log(arr);
}, e => {
console.log(e);
});

function getData4() {
return new Promise((resolve, reject) => {
setTimeout(() => {
// console.log('第四条数据加载成功');
reject('data4 err');
}, 500);
});
}

let p = Promise.all([]);
p.then(() => {
console.log('aaa');
}, e => {
console.log(e);
});

let count = 0;
let err = false;
function func() {
if (count < 4) return;
if (err) {
// ....
}
console.log('全部拿到了 !');
}

function getData1() {
setTimeout(() => {
console.log('第一条数据加载成功');
count ++;
func();
}, 1000);
}
function getData2() {
setTimeout(() => {
console.log('第二条数据加载成功');
count ++;
func();
}, 1000);
}
function getData3() {
setTimeout(() => {
console.log('第三条数据加载成功');
count ++;
func();
}, 1000);
}
function getData4() {
setTimeout(() => {
console.log('第四条数据加载成功');
count ++;
func();
}, 1000);
}
getData1();
getData2();
getData3();
getData4();

Promise.race()
- 与Promise.all() 相反,其中有1个参数是失败的,则最终决议失败,并立即将失败的结果返回。如果参数为空,将会一直被挂起。 Promise.race([ promise1, promise2 ]) : Promise
- Promise.race([p1, p2, p3])里面哪个结果获得的快,就返回哪个结果,不管结果本身是成功状态还是失败状态
function getData1() {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('第一条数据加载成功');
reject('err');
}, 500);
});
}
function getData2() {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('第二条数据加载成功');
resolve('data2');
}, 1000);
});
}
function getData3() {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('第三条数据加载成功');
resolve('data3');
}, 1000);
});
}
let p = Promise.all([getData1(), getData2(), getData3()]);
// let p = Promise.race([]);
p.then(data => {
console.log(data);
}, e => {
console.log(e);
})

let flag = false;
function func(data) {
if (flag) return;
flag = true;
console.log(data);
}
function getData1() {
setTimeout(() => {
console.log('第一条数据加载成功');
func({name: 'xiaoming'});
}, 500);
}
function getData2() {
setTimeout(() => {
console.log('第二条数据加载成功');
func({name: 'xiaohong'});
}, 600);
}
getData1();
getData2();

Promise.resolve(value) 和 Promise.reject(value)
常用来生成已经被决议为失败或者成功的promise实例。可以传递一个普通的值,或者传递一个promise实例。
- 传递一个普通的值
let p1 = new Promise(resolve => {
resolve('成功!');
});
// p2等同于p1
let p2 = Promise.resolve('成功!');
2.传递一个promise实例; value 本身就是 Promise 对象,则该对象作为 Promise.resolve 方法的返回值返回
let poruomiesi = new Promise(resolve => {
resolve('耶!')
});
// 直接返回传递进去的promise
let p = Promise.resolve(poruomiesi);
p.then(data => void console.log(data));
console.log(p === poruomiesi);

let p = {
then(cb) {
console.log('我被执行了');
cb('222');
},
oth() {
console.log('我不会执行');
}
};
let m = Promise.resolve(p).then(data => {
console.log(data);
// 我被执行了
// 222
});
Promise.reject()
Promise.reject({ then() { console.log(1) } })
.then(() => {
console.log('我不会被执行');
}, e => {
console.log(e); // 直接将上面传入的对象输出,不做任何处理
});

console.log(1);
let p = new Promise(resolve => {
console.log(2);
resolve();
console.log(3);
});
console.log(4);
p.then(() => {
console.log(5);
});
console.log(6);

将同步的任务转成异步任务
function createAsyncTask(syncTask) {
return Promise.resolve(syncTask).then(syncTask => syncTask());
}
createAsyncTask(() => {
console.log('我变成了异步任务!!!');
return 1 + 1;
}).then(res => {
console.log(res);
});
console.log('我是同步任务!');
