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才可以。

  

 

posted @ 2021-12-17 15:57  手残_夹心饼干  阅读(96)  评论(0)    收藏  举报