Promise相关内容(三)——异步获取服务器数据:promise方式解决回调地狱的问题。通过多个.then使代码可读性更高 & 实现异步任务的串行执行,保证按顺序发送请求获取数据

Promise相关内容(三)——异步获取服务器数据:promise方式解决回调地狱的问题。通过多个.then使代码可读性更高 & 实现异步任务的串行执行,保证按顺序发送请求获取数据

第一种形式:常规写法-正常

第一步:新建myapi文件夹

第二步:在文件夹myapi里面新建index.js和pubulic文件夹

第三步:在publice文件夹下新建文件01.html

内容如下:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>
<body>
  <div>Promise</div>
  <script type="text/javascript">
    /*
      如何获取异步的结果
    */
    function queryData () {
      let xhr = new XMLHttpRequest()
      xhr.open('get', 'data')
      xhr.send(null)
      xhr.onreadystatechange = function () {
        if (xhr.readyState === 4) {
          if (xhr.status === 200) {
            // 获取服务器响应的结果
            let ret = xhr.responseText
            console.log(ret)
          }
        }
      }
    }
    queryData()
    
    </script>
</body>
</html>

第四步:index.js文件如下:

const express = require('express');
const app = express();

// 启动静态资源服务
app.use(express.static('public'))

app.get('/data', (req, res) => {
  let info = {
    username: 'lisi',
    age: 12
  }
  // res.send('Hello World')
  res.json(info)
})

app.listen(3000, () => {
  console.log('running...')
})

第五步:在myapi文件夹下,命令行启动服务器

node index.js

第六步:打开页面,控制台验证获取数据——22行和服务器均验证成功

在这里插入图片描述

第二种形式:如果返回值形式验证,显示undefined
    function queryData () {
      let xhr = new XMLHttpRequest()
      xhr.open('get', 'data')
      xhr.send(null)
      xhr.onreadystatechange = function () {
        if (xhr.readyState === 4) {
          if (xhr.status === 200) {
            // 获取服务器响应的结果
            let ret = xhr.responseText
           // console.log(ret)
+          return ret            
          }
        }
      }
    }
-    queryData()
+    let ret = queryData()
+    console.log(ret)  

此时打印ret,显示为undefined

第三种形式:返回值形式验证,显示为null
    /*
      如何获取异步的结果
    */
  function queryData () {
    let xhr = new XMLHttpRequest()
    xhr.open('get', 'data')
    xhr.send(null)
 +   let ret = null
     // 回调函数(定义——由自己定义,由别人/浏览器调用)
    xhr.onreadystatechange = function () {
      if (xhr.readyState === 4) {
        if (xhr.status === 200) {
          // 获取服务器响应的结果
          // let ret = xhr.responseText
          // console.log(ret)
          // return ret

          ret = xhr.responseText
        }
      }
    }
    return ret   //为null原因:当返回值时,ret此时尚为空
  }
 // 异步的结果无法通过返回值的方式获取
 // 必须使用回调函数的方式获取
+  let ret = queryData()
+   console.log(ret)  

拿不到结果,显示为空。打印为显示为null

第四种形式:回调函数的方式获取数据验证,正常显示
单层回调
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>
<body>
  <div>Promise</div>
  <script type="text/javascript">
    /*
      如何获取异步的结果
    */
  function queryData (callback) {
    let xhr = new XMLHttpRequest()
    xhr.open('get', 'data')
    xhr.send(null)
    xhr.onreadystatechange = function () {
      if (xhr.readyState === 4) {
        if (xhr.status === 200) {
          // 获取服务器响应的结果
          let ret = xhr.responseText
          callback(ret)       
        }
      }
    }
   
  }
  // callback(ret)中的ret传给data
  queryData(function(data) {
    console.log(data)
  })

    </script>
</body>
</html>

打开页面,显示正常(回调函数,获取数据)

在这里插入图片描述

**变形写法:**加个路径,显示结果没有变化

注意写法对比,代码如下

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>
<body>
  <div>Promise</div>
  <script type="text/javascript">
    /*
      如何获取异步的结果
    */
+  function queryData (callback,path) {
    let xhr = new XMLHttpRequest()
+    xhr.open('get', path)
    xhr.send(null)
    xhr.onreadystatechange = function () {
      if (xhr.readyState === 4) {
        if (xhr.status === 200) {
          // 获取服务器响应的结果
          let ret = xhr.responseText
          callback(ret)       
        }
      }
    }
   
  }
  // callback(ret)中的ret传给data
  queryData(function(data) {
    console.log(data)
+  },'data')

    </script>
</body>
</html>

打印data,显示结果同上

多层回调,出现回调地狱,影响性能
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>
<body>
  <div>Promise</div>
  <script type="text/javascript">
    /*
      如何获取异步的结果
    */
  function queryData (callback,path) {
    let xhr = new XMLHttpRequest()
    xhr.open('get', path)
    xhr.send(null)
    xhr.onreadystatechange = function () {
      if (xhr.readyState === 4) {
        if (xhr.status === 200) {
          // 获取服务器响应的结果
          let ret = xhr.responseText
          callback(ret)       
        }
      }
    }
   
  }
  // callback(ret)中的ret传给data
  // queryData(function(data) {
  //   console.log(data)
  // },'data')
    // 回调地狱
  queryData(function(data) {
    console.log(data)
    queryData(function(data) {
      console.log(data)
      queryData(function(data) {
        console.log(data)
      }, 'data2')
    }, 'data1')
  }, 'data')

    </script>
</body>
</html>

多层回调,出现回调地狱,可读性不高,不推荐

在这里插入图片描述

为了解决上述问题(异步获取数据和多层嵌套出现的回调地狱),就诞生了Promise

实现异步任务的串行执行,按顺序执行任务,保证第一个异步任务的结果拿到后,再发请求进行第二个异步任务,依次类推;采用promise方式,不用嵌套,改为横向的水平关系(多个.then),代码的可读性更高,解决回调地狱的问题

单层数据获取
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>
<body>
  <div>Promise</div>
  <script type="text/javascript">
    /*
      如何获取异步的结果
    */
    function queryData (path) {
    return new Promise(function(resolve, reject) {
      // 处理异步任务
      let xhr = new XMLHttpRequest()
      xhr.open('get', path)
      xhr.send(null)
      // 回调函数(由自己定义,由别人调用)
      xhr.onreadystatechange = function () {
        if (xhr.readyState === 4) {
          if (xhr.status === 200) {
            // 获取服务器响应的结果
            let ret = xhr.responseText
            resolve(ret)
          }
        }
      }
    })
  }

  queryData('data')
    .then(ret => {
      console.log(ret)
    })
    </script>
</body>
</html>

显示结果正常

在这里插入图片描述

多层数据时,也正常
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>
<body>
  <div>Promise</div>
  <script type="text/javascript">
    /*
      如何获取异步的结果
    */
    function queryData (path) {
    return new Promise(function(resolve, reject) {
      // 处理异步任务
      let xhr = new XMLHttpRequest()
      xhr.open('get', path)
      xhr.send(null)
      // 回调函数(由自己定义,由别人调用)
      xhr.onreadystatechange = function () {
        if (xhr.readyState === 4) {
          if (xhr.status === 200) {
            // 获取服务器响应的结果
            let ret = xhr.responseText
            resolve(ret)
          }
        }
      }
    })
  }

  queryData('data')
    .then(ret => {
      console.log(ret)
      return queryData('data1')
    })
    .then(ret=>{
      console.log(ret)
      return queryData('data2')
    })
    .then(ret=>{
      console.log(ret)
    })
    </script>
</body>
</html>

显示正常

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值