Promise里边保存着未来才会结束的事件,从它可以获取异步操作的消息。
- 三种状态: 创建,成功和失败。
Promise执行流程
let promise = new Promise(function(resolve, reject){
let random = ~~Math.random();
if(random) {
resolve(random);
} else {
reject(random);
}
})
- 实例化promise 对象,立即执行promise。
- 如果random是1 ,执行resolve函数,修改promise状态为成功,将random的值传递出去
- 如果random是2, 执行reject函数,修改promise状态为失败,将randon的值传递出去
promise.then(value => console.log(value, '成功'), value => console.log('失败'));
4. Promise.prototype.then方法,只有在promise 的状态被修改为成功/失败才会执行,(resolve/reject执行);
- 第一个参数: 设置 异步操作执行成功的回调
- 第二个参数: 设置异步操作执行失败的回调
then的回调只有在当前的同步代码执行完成后,才会执行
应用:
回调地狱的问题
先做饭,做完饭后再吃饭, 吃完饭后再洗碗。
有严格的顺序,而且回调的参数一直嵌套
同步代码
function cook(eat) {
setTimeout(() => {
console.log('做完饭了')
eat && eat(function wash(){
setTimeout(() => {
console.log('洗洗刷刷, 完成!');
}, 3000)
});
}
, 2000);
}
function eat(wash) {
setTimeout(() => {
console.log('吃完啦');
wash && wash();
}, 5000);
}
cook(eat);
// 执行cook, 将eat作为回调, 做完饭后执行eat
// 执行eat, 将wash作为回调, 吃完饭后执行wash
问题: 函数嵌套,造成回调地狱
promise异步解决方案: promise 的then 链式调用
promise 的then , 异步操作成功, 执行第一个回调,执行完成后; 返回一个新的promise ,执行promise 。 保证两个异步操作的顺序性
function cook(){
return new Promise(function(resolve, reject){
console.log('西红柿炒蛋做好了');
resolve();
})
}
// 创建新的promise, 立即执行,修改promise的状态为成功
function eat() {
return new Promise(function(resolve, reject){
console.log('吃过了!');
resolve();
})
}
// 创建新的promise, 立即执行,修改promise的状态为成功
function wash() {
return new Promise(function(resolve, reject){
console.log('洗洗碗');
resolve();
})
}
// 创建wash的promise, 立即执行,修改promise的状态为成功
let pro1 = cook();
pro1.then(() => {
return eat();
}).then(() => {
return wash();
}).then(() => {
console.log('可以歇息了');
})
核心: 通过实例化promise,立即执行操作,执行完成后修改promise的状态,在promise. then方法中确定成功后的回调是什么~
异步加载,避免堵塞
加载文件等的时候,同步加载太过于缓慢,使用异步加载, 只需要创建多个 promise ,多个promise同时工作,谁先完成,就先执行 回调,速度快。
function iminateReadFile(file) {
return new Promise(function(resolve, reject){
setTimeout(() => {
let time = Date.now();
let value = `文件${file}加载完成`;
resolve({value, time});
}
, Math.random() * 2000);
})
}
// 模拟文件的加载,穿入文件路径,通过定时器模拟文件加载的时长,
let startTime = Date.now();
let pro1 = iminateReadFile('a.txt'); // a文件,创建promise,开始计时
let pro2 = iminateReadFile('b.txt'); // b文件, 创建promise, 开始计时
let pro3 = iminateReadFile('c.txt'); // c文件,创建promise, 开始计时
// 三个文件同时加载,谁先执行完,谁的then方法先调用
pro1.then(({value, time}) => {
console.log(value, time - startTime);
})
pro2.then(({value, time}) => console.log(value, time - startTime));
pro3.then(({value, time}) => console.log(value, time - startTime));
// then的回调执行的前提是所有的同步代码都执行完了
每次执行函数,都会创建一个promise,创建的多个promise同步执行,谁先执行完,谁的then的回调就先执行,不会浪费时间。