你没见过的回调地狱,我替你去看了——Promise模式
小金今天刚敲完代码,就收到了一条短信:你就和我在一起吧,我Promise以后会让你幸福的。原来是他的房东又向他抛来了橄榄枝,小金听完这个Promise,赶紧收拾行李,连夜跑回(
.then
)老家,此时不走更待何时......
让我们一起走进今天的分享,Promise如何解回调地狱的......
一、异步与同步
- 同步: 在同步操作中,程序的执行流会等待一个操作完成后再继续下一步。例如,当你调用一个同步函数时,程序会暂停并等待该函数返回结果,期间不会执行任何其他操作。
- 异步: 在异步操作中,程序发起一个操作后立即继续执行,不会等待操作完成。操作完成后,通常会通过回调函数、事件、状态更改或通知等方式来告知主程序操作的结果。
简单的来说,花费时间的函数,它们允许程序在等待这些操作完成的同时继续执行其他任务,我们称为异步函数,比如向后端请求数据、事件监听、setTimeout()
......
- 下面来看一段代码示例,你觉得它会输出什么呢?
var a = 1
setTimeout(()=>{
a = 2
},1000)
console.log(a);
答案是:1,在箭头函数执行之前,v8已经将所有的同步函数执行完毕了,然后再修改的a的值为2。
简单的理解了这个之后,我们直接上强度!
二、回调小地狱
- 假设有一个函数a,它的执行要函数b的执行返回的结果,函数b的执行要函数c的执行返回的结果,函数c的执行要函数d的执行返回的结果。先不管脑子是不是要烧了,咱们先看代码......
function a (cbB,cbC,cbD){
cbB(cbC,cbD)
}
function b (cb,cbD){
cb(cbD)
}
function c (cb){
cb()
}
function d (){}
a(b,c,d)
a函数接受三个回调参数:cbB、cbC和cbD
。cbB实际上为b函数,它又接收 cb
和 cbD
参数。cb
参数实际上是指向 c
函数的引用,它接收一个回调参数 cb
并立即调用它。cbD
参数是指向 d
函数的引用,它没有参数。如果觉得已经转不过来了,那么直接请上我们的Promise老祖!
三、Promise的使用
Promise
是一个异步编程模式,主要用于处理异步操作,如果将上述的程序理解为函数a的执行需要函数b的拿到数据,函数b的执行需要函数c拿到的数据......这样的场景在现实开发中是很常见的,Promise提供了一种更优雅的方式来组织和处理非阻塞的异步代码,可以更加合理和强大的代替回调函数的方式。Promise
对象有三种状态:Pending(挂起)、Fulfilled(成功)、Rejected(失败) 其后两个会有返回值。当调用这些函数后,Promise就会改变成相应的状态。- 创建Promise
promise
.then((result) => {
console.log(result);
})
.catch((error) => {
console.error(error);
});
注: then()
方法是在Promise的原型对象上的,只有Promise对象才有这个方法。
Promise
的链式调用,以相亲的实例来体验一下吧,彭于晏们
function xq(){
return new Promise((resolve,reject)=>{ //{status:Fulfilled}
setTimeout(() => {
console.log('你要相亲了');
resolve()
}, 2000);
})
}
function marry(){
return new Promise((resolve,reject)=>{
setTimeout(() => {
console.log('你们结婚了');
resolve()
}, 1000);
})
}
function baby(){
console.log('孩子出生了');
}
xq().then(()=>{
return marry()
})
.then(()=>{
baby()
})
这种模式更加直观和流畅的展现了异步操作的流程,但是特别注意的是,then方法会默认返回一个
Promise
对象,状态为pending
,如果你没有主动返回marry
中的Promise
的话,第一个then默认返回的Promise
对象会继承前一个Promise的结果或错误,也就是不等marry执行完,就会先一步执行。
- 你可以通过
resolve()
和reject()
调用传递参数(请求到的数据、错误信息),和改变Promise的状态。
Promise变为Fulfill状态
function a(){
return new Promise((resolve,reject)=>{
setTimeout(()=>{
console.log('a is ok');
resolve('请求到的数据')
},1000)
})
}
a()
.then((res)=>{
console.log(res,'11111111');
})
Promise变为reject状态
function a(){
return new Promise((resolve,reject)=>{
setTimeout(()=>{
console.log('a is ok');
reject('no')
},1000)
})
}
a()
.then((res)=>{
console.log(res,'11111111');
})
.catch((err)=>{
console.log(err,"xxxxxxxxxxx");
})
接下来!我们用Promise解决一下刚刚的回调小地狱吧!!!
function a() {
return new Promise((resolve) => {
resolve(b());
});
}
function b() {
return new Promise((resolve) => {
resolve(c());
});
}
function c() {
return new Promise((resolve) => {
resolve(d());
});
}
function d() {
// 这个函数可以返回任何你想返回的结果
return "Result from D";
}
// 使用 Promise 链式调用
a()
.then(() => b())
.then(() => c())
.then(() => d())
.then((result) => {
console.log(result); // 输出 "Result from D"
})
是不是感觉柳暗花明又一村了呢~~~
转载自:https://juejin.cn/post/7385832570184319014