Promise详解

什么是Promise

Promise 是 ES6 引入的异步编程的新解决方案。语法上 Promise 是一个构造函数,用来封装异步操作
并可以获取其成功或失败的结果;

为什么要使用Promise

Promise比较常见的使用场景就是网络请求(网络请求是异步操作),当我们发起一个请求时不能立即拿到结果,所以我们会传入另外一个函数,在数据请求成功时,将数据通过传入的函数回调出去。

如果是一个简单的网络请求不会对我们带来较大的困惑

但是在实际开发中,往往需要我们先拿到请求的数据,在去执行同步的任务,所以Promise可以使我们的异步代码看起来像同步代码一样

这里我们先来举一个栗子;现在有一个需求:小明在快餐店想要喝奶茶和吃火锅,奶茶是2秒做出了,火锅是4秒做出了,我们可以通过代码来实现

// 做奶茶的函数
function getTea(fn) {
  setTimeout(() => {
    fn("奶茶");
  }, 2000);
}

// 做火锅的函数
function getHotpot(fn) {
  setTimeout(() => {
    fn("火锅");
  }, 4000);
}

getTea(function (data) {
  console.log(data);
});

getHotpot(function (data) {
  console.log(data);
});

在这里插入图片描述
现在的奶茶和火锅已经做出来了,但是小明又想先吃火锅,在喝奶茶,这时候我们可以这样做

function getHotpot(fn) {
  setTimeout(() => {
    fn("火锅");
    setTimeout(() => {
      fn("奶茶");
    }, 2000);
  }, 4000);
}

getHotpot(function (data) {
  console.log(data);
});

在这里插入图片描述
这样可以实现效果,那现在小明又想先吃火锅,在喝奶茶,在去游泳,在去上网,在去健身,在去弹吉他…

我们看下面代码

function getHotpot(fn) {
  setTimeout(() => {
    fn("火锅");
    setTimeout(() => {
      fn("奶茶");
      setTimeout(() => {
        fn("游泳");
        setTimeout(() => {
          fn("上网");
          setTimeout(() => {
            fn("健身");
            setTimeout(() => {
              fn("弹吉他");
            }, 2000);
          }, 2000);
        }, 2000);
      }, 2000);
    }, 2000);
  }, 4000);
}

看这一坨代码头都大了,可维护性实在是很低,这其实就是回调地狱

这个时候,Promise的作用就会显得尤为重要

Promise的使用

Promise是一个对象,我们可以通过创建Promise对象来使用Promise,Promise有两个参数resolve和reject、分别是获取成功和获取失败的结果,获取成功可以返回成功后的数据,获取失败可以返回错误信息,然后使用then方法可以拿到获取成功后的数据

let p = new Promise(resolve => resolve("hello world"));
p.then(data => console.log(data));

在这里插入图片描述

解决回调地狱

知道了Promise的基本使用我们就可以解决上面那个栗子回调地狱的问题

function getHotpot() {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve("火锅");
    }, 2000);
  });
}

function getTea() {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve("奶茶");
    }, 1000);
  });
}

function gatBodybuilding() {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve("健身");
    }, 1000);
  });
}

getHotpot()
  .then(data => {
    console.log(data);
    return getTea();
  })
  .then(data => {
    console.log(data);
    return gatBodybuilding();
  })
  .then(data => console.log(data));

在这里插入图片描述
这样我们就可以通过返回Promise对象使用then方法来进行链式调用,大大加强了代码的可维护性

解决回调地狱的终极解决方案:Promise语法糖 async await

上面的那种方法虽然已经解决了回调地狱的问题 ,但是凭借朴实的情感和直观的感受并不是很好,所以async await是更好的解决方案

function getHotpot() {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve("火锅");
    }, 2000);
  });
}

function getTea() {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve("奶茶");
    }, 6000);
  });
}

function gatBodybuilding() {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve("健身");
    }, 1000);
  });
}

async function getData() {
  let hotpot = await getHotpot();
  console.log(hotpot);
  let tea = await getTea();
  console.log(tea);
  let bodybuilding = await gatBodybuilding();
  console.log(bodybuilding);
}

getData();

在这里插入图片描述
async 函数必须有await ,await接收必须是一个promise对象

这样的代码看起来会更加优雅,可维护性也会非常的高,这也是最开始提到的可以让异步的代码看起来更像是同步的代码。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值