在 JavaScript 的世界中, 所有代码都是单线程执行的。 由于这个“缺陷”, 导致 JavaScript 的所有网络操作, 浏览器事件, 都必须是异步执行。 使用Promise可以解决这个问题。
一、Promise异步编排
1.异步编排案例
案例需求: 用户登录, 并展示该用户的各科成绩。 在页面发送两次请求:
- 查询用户, 查询成功说明可以登录。
- 查询用户成功, 查询科目。
- 根据科目的查询结果, 获取成绩。
分析: 此时后台应该提供三个接口, 一个提供
用户查询接口
, 一个提供科目接口
, 一个提 供各科成绩接口
, 为了渲染方便, 最好响应 json 数据。 在这里就不编写后台接口了, 而 是提供三个 json 文件, 直接提供 json 数据, 模拟后台接口:
user.json:
{
"id": 1,
"name": "zhangsan",
"password": "123456"
}
user_corse_1.json:
{
"id": 10,
"name": "chinese"
}
corse_score_10.json:
{
"id": 100,
"score": 90
}
不使用ES6实现:
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
...
<script>
$.ajax({
url: "mock/user.json",
success(data) {
console.log("查询用户: ", data);
$.ajax({
url: `mock/user_corse_${
data.id}.json`,
success(data) {
console.log("查询到课程: ", data);
$.ajax({
url: `mock/corse_score_${
data.id}.json`,
success(data) {
console.log("查询到分数: ", data);
},
error(error) {
console.log("出现异常了: " + error);
}
});
},
error(error) {
console.log("出现异常了: " + error);
}
});
},
error(error) {
console.log("出现异常了: " + error);
}
});
</script>
使用ES6实现:
<script>
// 1.使用Promise封装异步操作
let p = new Promise((resolve, reject) => {
// 2. 异步操作
$.ajax({
url: "mock/user.json",
success: function (data) {
console.log("查询用户成功:", data)
resolve(data)
},
error: function (err) {
reject(err);
}
});
});
p.then((obj) => {
return new Promise((resolve, reject) => {
$.ajax({
url: `mock/user_corse_${
obj.id}.json`,
success: function (data) {
console.log("查询用户课程成功:", data)
resolve(data);
},
error: function (err) {
reject(err);
}
});
})
}).then((data) => {
console.log("上一步的结果:", data)
$.ajax({
url: `mock/corse_score_${
data.id}.json`,
success: function (data) {
console.log("查询课程得分成功:", data)
},
error: function (err) {
}
});
})
</script>
2.使用Promise优化
将Promise封装。
- 用Promise封装异步操作。
- 用resolve将成功操作向下传递。
- 用reject将失败操作向下传递。
<script>
// 将Promise封装
function get(url, data) {
return new Promise((resolve, reject) => {
$.ajax({
url: url,
data: data,
success: function (data) {
resolve(data);
},
error: function (err) {
reject(err)
}
})
});
}
get("mock/user.json")
.then((data) => {
console.log("用户查询成功:", data)
return get(`mock/user_corse_${
data.id}.json`);
})
.then((data) => {
console.log("课程查询成功:", data)
return get(`mock/corse_score_${
data.id}.json`);
})
.then((data)=>{
console.log("课程成绩查询成功:", data)
})
.catch((err)=>{
console.log("出现异常",err)
});
</script>
二、模块化
模块化是编写大型项目的基础,类似于Java中的导包,JS中没有导包的概念,取而代之的是模块化。
- export命令:用于规定模块的对外接口。
- import命令:用于导入其他模块提供的功能。
准备三个JS文件,演示模块化的导入导出:
hello.js
export const util = {
sum(a, b) {
return a + b;
}
}
// export不仅可以到处对象,一切JS变量都可以导出.比如基本类型变量,函数,数组,对象.
// export{util}
main.js
import util from "./hello.js"
import {
name,age,add} from "./user.js"
util.sum(1,2);
console.log(name+age);
add(1,3);
user.js
var name = "jack";
var age = "21";
function add(a,b){
return a + b;
}
export{
name,age,add}