• 你真的会Promise的使用吗?
  • 发布于 2个月前
  • 95 热度
    0 评论
  • Spring
  • 0 粉丝 43 篇博客
  •   

小金今天刚敲完代码,就收到了一条短信:你就和我在一起吧,我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);
    })
}
// 堆代码 duidaima.com
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"
    })
是不是感觉柳暗花明又一村了呢~~~
用户评论