「这是我参与2022首次更文挑战的第27天,活动详情查看:2022首次更文挑战」。
嗨,大家好,我是Starqin,昨天趁着周六的时间,回顾了以下Promise,今天借着写这篇文章的机会,再来复习一遍
Promise英译汉的意思是承诺、保证的意思。
Promise有三种状态,我分别用代码来引导出来
等待状态
let myPro = new Promise((res, rej) => {});
console.log(myPro);
上面这段代码实例化了一个promise对象,并且没有对promise进行任何操作。此时控制台中输出以下内容
黄色方框中PromiseState的值是pending。表示Promise进入等待状态
注意在实例化Promise时我们需要在构造函数中传入一个带有两个参数的回调函数,其中第一个参数,表示成功,第二个参数表示失败,这两个参数,您可以自定义名称,但是他们所代表的逻辑您无法改变。
成功状态
let myPro = new Promise((res, rej) => {
res();
});
console.log(myPro);
当我在Promise构造函数回调方法中调用第一个参数时,控制台输出如下:
黄色方框中PromiseState的值是fulfilled。表示Promise进入成功状态状态
接着我在调用res时,传递一个参数
let myPro = new Promise((res, rej) => {
res("W-js are you ok?");
});
console.log(myPro);
此时控制台中的输出,如下
可以看到,PromiseResult的值不再是undfined,而是我们在调用res函数时传递的参数
失败状态
let myPro = new Promise((res, rej) => {
rej("乌克兰怎么啦?");
});
console.log(myPro);
控制台输出如下:
当我们调用rej函数时,PromiseState的值为rejected,表示promise进入失败状态,并且会给我们报一个错误,PromiseResult的值是我们传递给rej函数的参数
then方法
每一个Promise对象都有一个then方法,then方法又有两个回调函数,onResoLved、onRejected,其中onResoLved是当Promise对象状态为成功时调用的函数,onRejected是Promise对象状态为失败时调用的函数。
<script>
let myPro = new Promise((res, rej) => {
rej("乌克兰怎么啦?");
});
myPro.then(
() => {
console.log('Promise处于成功状态');
}, () => {
console.log("promise处于失败状态")
})
</script>
控制台输出
当我们在Promise构造函数中调用res函数时,控制台的输出结果:
注意then方法中的两个回调函数,是可以接收参数的,且这个参数就是Promise中调用res或rej的参数,请看一下代码
<script>
let myPro = new Promise((res, rej) => {
res("W-js are you ok?");
//rej("乌克兰怎么啦?");
});
myPro.then(
(myRes) => {
console.log(myRes,'当然,我Js很好');
}, () => {
console.log("promise处于失败状态")
})
</script>
控制台的输入结果
then也是有返回值,其返回值无论在什么状态下都会返回一个Promise对象,这样的呃特性,也就导致Promise可以进行链式操作
Promise实操
我有以下代码,需要在输出111后在输出222,然后在输出333
function app1() {
setTimeout(() => {
console.log(111);
}, 1000)
}
function app2() {
setTimeout(() => {
console.log(222);
}, 1000)
}
function app3() {
setTimeout(() => {
console.log(333);
}, 1000)
}
有的人肯第一时间会这样解答:
app1();
app2();
app3();
依次调用这些函数,控制台中的输出结果
虽然表面上是实现了这样的效果,但是实际上,由于setTimeout中的回调函数是一个异步代码,且等待时间是一秒钟。这也就导致111,222,333是同一时间被输出的,没有达到最终的要求
此时我们原生的解决方法是
function app1() {
setTimeout(() => {
console.log(111);
app2();
}, 1000)
}
function app2() {
setTimeout(() => {
console.log(222);
app3()
}, 1000)
}
function app3() {
setTimeout(() => {
console.log(333);
}, 1000)
}
app1();
这样的操作结果就能够达到要求,111,222,333是被依次输出到控制台的,但是如果我将上面这段代码改写成以下这种形式
<script>
function app1() {
setTimeout(() => {
console.log(111);
setTimeout(() => {
console.log(222);
setTimeout(() => {
console.log(333);
}, 1000)
}, 1000)
}, 1000)
}
app1();
</script>
大家可以看到这样的写法虽然直观,但是代码嵌套关系复杂,嵌套结构很深,我们称这种状况为回调地狱,而promise就是为了解决回调地狱应运而生的
将以上代码改写成Promise
function app1() {
return new Promise((res) => {
setTimeout(() => {
res('111')
}, 1000)
})
}
app1().then(res => {
console.log(res);
return new Promise((res) => {
setTimeout(() => {
res('222')
}, 1000)
})
}).then(res => {
console.log(res);
return new Promise((res) => {
setTimeout(() => {
res('333')
}, 1000)
})
}).then(res => {
console.log(res);
})
上面的这种代码结构极大程度解决了回调函数的嵌套问题
以上代码优化:
<script>
function app1(text) {
return new Promise((res) => {
setTimeout(() => {
res(text)
}, 1000)
})
}
app1(111).then(res => {
console.log(res);
return app1(222);
}).then(res => {
console.log(res);
return app1(333)
}).then(res => {
console.log(res);
})
</script>