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>
显示正常