浅学一下promise

1、为什么需要promise

主要解决回调地狱问题

一个回调地狱的例子:

通过Ajax请求获取一个id,再根据id请求用户名,然后再根据用户名获取其他信息...

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script src="./common/jquery.min.js"></script>
</head>
<body>
  <script>
    // 先发一个请求拿到一个id
    $.ajax({
      url: './public/id.json',
      type: 'GET',
      success: function(res1) {
        const {id} = res1
        console.log('id', id);

        // 再发一个Ajax请求,根据id去获取用户名
        $.ajax({
          type: "GET",
          url: "./public/username.json",
          data: {id},
          success: function(res2) {
            const {username} = res2;
            console.log("username:" , username);

            // 再根据用户名去拿地址
            $.ajax({
              type: "GET",
              url: "./public/address.json",
              data: {username},
              success: function(res3) {
                const {address} = res3;
                console.log("address", address);
              }
            })
          }
        })
      }
    })
  </script>
</body>
</html>

输出:
id 1
username: codeyu
address china

这样就陷入了回调地狱,每次都要在请求的回调函数中嵌套请求及其回调,这对于我们代码的阅读和维护是几不友好的。

2. promise的基本使用

Promise 是一个构造函数 ,通过new关键字实例化一个对象

1)语法:

js 复制代码
new Promise((resolve, reject)=>{})

Promise接受一个函数作为参数,参数函数中接受两个参数:

  • resolve函数
  • reject函数

promise实例有两个属性:

  • status,初始状态是pending
  • result

2)promise状态

  • pending:(准备,待解决,进行中)
  • fulfilled:(已完成)
  • rejected(已拒绝)

promise状态的改变:通过调用resolve()reject()

示例:

js 复制代码
const p = new Promise((resolve,reject) => {
    resolve(); 
    // reject();)
})
console.dir(p)
  • 调用resolve(),将promise的状态从pending改变为fulfilled
  • 调用reject(),将promise的状态从pending改变为rejected

注意:promise对象的状态改变是一次性的,只能从pending到其他两种状态

3)promise的结果

示例:

js 复制代码
    const p = new Promise((resolve,reject)=> {
      // 通过调用resolve并传递参数,改变当前promise对象的结果
      // resolve('success')
      reject('failed')
    })
    console.log(p);

3. promise的方法

1)then方法

参数:

js 复制代码
    const p = new Promise((resolve,reject)=> {
      resolve('success')
      // reject('failed')
    })
    // 参数:
    // 1.是一个函数
    // 2.还是一个函数
    console.dir(p);
    p.then(()=> {
      // 当promise的状态是fulfilled
      console.log("成功时调用");
    },() => {
      // 当promise的状态是rejected
      console.log("失败时调用");
    })

数据接收:

js 复制代码
	const p = new Promise((resolve,reject)=> {
      resolve('success')
      // reject('failed')
    })
    // then接收数据
    console.dir(p);
    p.then((value)=> {
      // 当promise的状态是fulfilled
      console.log("成功时调用",value);
    },(reason) => {
      // 当promise的状态是rejected
      console.log("失败时调用",reason);
    })

在then方法的参数函数中,通过形参接收promise对象的结果。

返回值:是一个新的promise实例,状态是pending

js 复制代码
    const p = new Promise((resolve,reject)=> {
      resolve('success')
      // reject('failed')
    })
    // then接收数据
    console.dir(p);
    const res = p.then((value)=> {
      // 当promise的状态是fulfilled
      console.log("成功时调用",value);
    },(reason) => {
      // 当promise的状态是rejected
      console.log("失败时调用",reason);
    })
    console.log(res);
    // 链式调用
    // new Promise((res,rej)=>{}).then().then()
  </script>

返回实例的状态改变:

promise的状态不改变,不会执行then方法,

**在then方法中 使用return可以将then返回的实例的状态改为fulfilled **

**在then方法中 代码出错,会将then返回的实例的状态改为rejected **

js 复制代码
new Promise( (res,rej) => {
  res('111')
}).then( (value)=> {
  console.log("success",value);
  // 使用return可以将then返回值实例的状态改为fulfilled
  return 123
},()=> {
  console.log("failed");
}).then( (value)=> {
  console.log("success",value);
},()=> {
  console.log("failed");
})


new Promise( (res,rej) => {
  res('111')
}).then( (value)=> {
  console.log("success",value);
  // 使用return可以将then返回值实例的状态改为fulfilled
  // return 123
  // 如果这里的代码出错,会把then返回值实例的状态改为rejected
  console.log(a);
},()=> {
  console.log("failed");
}).then( (value)=> {
  console.log("success",value);
},(reason)=> {
  console.log("failed",reason);
})

2)catch方法

执行时机:

promise的状态改为rejected时, promise执行体中代码出错或者抛出一个错误

类似then方法的第二个参数函数

js 复制代码
const p = new Promise( (resolve,reject) => {
  // reject('fail')
  console.log(a);
})
// 执行时机:
// promise的状态改为rejected时,
// promise执行体中代码出错或者抛出一个错误
p.catch( ()=> {
  console.log("failed");
})

常见写法

js 复制代码
new Promise((resolve,reject) => {

}).then((value) => {
  console.log(value);
}).catch((reason) => {
  console.log(reason);
})

4. promise解决回调地狱

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script src="./common/jquery.min.js"></script>
</head>
<body>
  <script>
    // 先发一个请求拿到一个id
    new Promise ( (resolve, reject) => {
      $.ajax({
        url: './public/id.json',
        type: 'GET',
        success: function(res1) {
          resolve(res1) // 修改promise的状态为fulfilled,结果为res1
        },
        error: function (err) {
          reject(err)
        }
      })
    }).then( (value)=> {
      console.log(value);
      const {id} = value;
      return new Promise((resolve, reject) => {
        $.ajax({
          url: './public/username.json',
          type: 'GET',
          data: {id},
          success: function(res1) {
            resolve(res1) // 修改promise的状态为fulfilled,结果为res1
          },
          error: function (err) {
            reject(err)
          }
        })
      })
    }).then( (data) => {
      const {username} = data;
      console.log(username);
      return new Promise((resolve, reject) => {
        $.ajax({
          url: './public/address.json',
          type: 'GET',
          data: {username},
          success: function(res1) {
            console.log(res1) // 修改promise的状态为fulfilled,结果为res1
          },
          error: function (err) {
            console.err(err)
          }
        })
      })
    })
  </script>
</body>
</html>
js 复制代码
代码优化

function getData(url,data = {}) {
  return new Promise ( (resolve, reject) => {
    $.ajax({
      url: url,
      type: 'GET',
      data: data,
      success: function(res1) {
        resolve(res1) // 修改promise的状态为fulfilled,结果为res1
      },
      error: function (err) {
        reject(err)
      }
    })
  })
}
getData('public/id.json')
  .then ((data) => {
    const {id} = data;
    return getData('public/username.json',{id})
  })
  .then( (data) => {
    const {username} = data;
    return getData('public/address.json', {username})
  }).then ( (data) => {
    console.log(data);
  })
相关推荐
小刘不知道叫啥23 分钟前
从异步传染浅谈代数效应
前端·javascript·reactjs
圈圈的熊24 分钟前
EZUIKit.js萤石云vue项目使用
前端·javascript·vue.js
hakesashou25 分钟前
python 怎么调用js
前端·javascript·python
xgq37 分钟前
使用ResizeObserver监测元素尺寸变化
前端·javascript·面试
wang_san_sui_1 小时前
VUE.js笔记
javascript·vue.js·笔记
宋小土2 小时前
Naive UI 选择器 Select 的:render-label 怎么使用(Vue3 + TS)
开发语言·前端·javascript·vue.js·ui
打野赵怀真2 小时前
要实现一个js的持续动画,你有什么比较好的方法?
前端·javascript
梦想CAD控件2 小时前
如何在网页CAD中创建三维建筑墙体(WEB三维CAD SDK)
前端·javascript·vue.js
不吃香菜的猪2 小时前
vue自定义div弹窗打开失败
前端·javascript·vue.js