Promise怎么用???
Promise
用来解决异步操作,使异步操作编写更简洁,不用一直回调(callback)
promise是通过自身状态,来控制异步操作的,通常promise有三个状态
异步操作未完成 pending
异步操作完成 fulfilled
异步操作失败 rejected
未完成------>成功 Promise 返回一个值(value),状态变为fulfilled。
未完成------>失败 Promise 抛出一个错误(error),状态变为rejected。
fulfilled(异步操作完成) + rejected(异步操作失败) = resolved(已定型)
1、Promise的构造函数的参数,是一个函数,并且该函数,又有2个参数,一个是resolve函数,一个是reject函数
new Promise((resolve,reject)=>{
//这里是执行的异步代码?????
if(/* 异步操作成功 */){
resolve(value);
/* 异步操作失败 */
}else{
reject(new Error());
}
});
2、resolve或reject执行前改变数据
let testNum = 0;
function test() {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log(11111);
testNum = 1;
}, 1000);
setTimeout(() => {
console.log(22222);
testNum = 2; //resolve执行前赋值
resolve(testNum);
}, 2000);
setTimeout(() => {
console.log(33333, '实际变量testNum:' + testNum);
testNum = 3;
}, 3000);
});
}
test().then((value) => {
let copyNum = testNum;
console.log('传入参数testNum:' + value, '------', '实际变量testNum:' + testNum, '++++++++++++')
});

resolve或reject执行前,改变数据,then中得到改变后的数据
3、resolve或reject执行后改变数据
let testNum = 0;
function test() {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log(11111);
testNum = 1;
}, 1000);
setTimeout(() => {
console.log(22222);
testNum = 2; //resolve执行前赋值
setTimeout(() => { testNum = -1 }, 0);
resolve(testNum);
}, 2000);
setTimeout(() => {
console.log(33333, '实际变量testNum:' + testNum);
testNum = 3;
}, 3000);
});
}
test().then((value) => {
let copyNum = testNum;
console.log('传入参数testNum:' + value, '------', '实际变量testNum:' + testNum, '++++++++++++')
});

加个setTimeout,时间为0执行,因为setTimeout会最后执行,这时resolve或reject已经执行完毕,then中testNum仍然是2,但实际上testNum已经变成了-1;
结论:Promise是在执行完resolve或reject后,立即执行then,如果在resolve或reject执行完成时,仍有代码没有执行完,那then里获取到的数据,只能是resolve或reject执行完之前的数据。
console.log(111111);
setTimeout(() => {
console.log(222222);
}, 0)
new Promise((resolve) => {
resolve(333333);
}).then((data) => {
console.log(data);
})
console.log(444444);

代码执行结果是,先执行console.log(111111)和console.log(444444),再执行promise,最后执行setTimeout;
综上,正常代码先执行,然后是promise,最后是setTimeout。(then的回调函数的执行时间,早于setTimeout(fn, 0)。因为then是本轮事件循环执行,setTimeout(fn, 0)在下一轮事件循环开始时执行。----------大神的解释)
let countNum = 0;
let interval;
let p = new Promise((resolve) => {
interval = setInterval(() => {
countNum++;
console.log(countNum);
if (countNum == 5) {
clearInterval(interval)
resolve(countNum);
}
}, 1000);
});
p.then((num) => {
for (let i = 1; i < 6; i++) {
num++;
}
let startTime = new Date();
for (let i = 0; i < 5000; i++) {
for (let j = 0; j < 1000; j++) {
for (let k = 0; k < 1000; k++) {
num++;
}
}
}
let endTime = new Date();
console.log("执行这段for循环用时:" + (endTime - startTime) + "ms");
setTimeout(() => { num = -1 }, 0);
return num;
}).then((num) => {
console.log(num, "+++++++++++++++++++++")
})

promise执行异步操作后,会在异步操作返回结果后执行resolve,然后执行第一个then。
但是,进入第二个then后,不会等第一个then的异步和setTimeout,会在第一个then的程序同步执行完后,立即执行,这里我们用一个for循环进行测试,for循环会执行一段时间,第二个then会在for循环执行完以后才执行。
let countNum = 0;
let interval;
let p = new Promise((resolve) => {
interval = setInterval(() => {
countNum++;
console.log(countNum);
if (countNum == 5) {
clearInterval(interval)
resolve(countNum);
}
}, 1000);
});
p.then((num) => {
for (let i = 1; i < 6; i++) {
num++;
}
return new Promise((resolve) => {
interval = setInterval(() => {
num++;
console.log(num);
if (num == 15) {
clearInterval(interval)
resolve(num);
}
}, 1000);
});
}).then((num) => {
console.log(num, "+++++++++++++++++++++")
})

如需要第二个then也在第一个then异步执行完后再执行,那就需要在第一个then里再return一个promise才可以。
浙公网安备 33010602011771号