1.Promise初体验
1.1异步任务抽奖案例
抽奖规则:
-
点击按钮, 1s 后显示是否中奖(30%概率中奖)
-
若中奖弹出 “恭喜恭喜, 奖品为 10万 RMB 劳斯莱斯优惠券”
-
若未中奖弹出 “再接再厉”
规则说明:
因为抽奖一般会把数据传回到后台,所以我们延时1s来模拟数据传输到后台,然后从后台获取返回结果的过程。
页面结构:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>基本使用</title>
<link crossorigin='anonymous' href="https://cdn.bootcss.com/twitter-bootstrap/3.3.7/css/bootstrap.min.css"
rel="stylesheet">
</head>
<body>
<div class="container">
<h2 class="page-header">Promise 初体验</h2>
<button class="btn btn-primary" id="btn">点击抽奖</button>
</div>
<script>
//生成随机数
function rand(m, n) {
return Math.ceil(Math.random() * (n - m + 1)) + m - 1;
}
</script>
</body>
</html>
1.1.1实现方法一:定时器
/**
点击按钮, 1s 后显示是否中奖(30%概率中奖)
若中奖弹出 恭喜恭喜, 奖品为 10万 RMB 劳斯莱斯优惠券
若未中奖弹出 再接再厉
*/
//获取元素对象
const btn = document.querySelector('#btn');
//绑定单击事件
btn.addEventListener('click', function () {
//定时器
setTimeout(() => {
//30% 1-100 1 2 30
//获取从1 - 100的一个随机数
let n = rand(1, 100);
//判断
if (n <= 30) {
alert('恭喜恭喜, 奖品为 10万 RMB 劳斯莱斯优惠券');
} else {
alert('再接再厉');
}
}, 1000);
});
1.1.2实现方法二:Promise形式实现
/**
点击按钮, 1s 后显示是否中奖(30%概率中奖)
若中奖弹出 恭喜恭喜, 奖品为 10万 RMB 劳斯莱斯优惠券
若未中奖弹出 再接再厉
*/
//获取元素对象
const btn = document.querySelector('#btn');
//绑定单击事件
btn.addEventListener('click', function () {
//Promise 形式实现
// resolve 解决 函数类型的数据
// reject 拒绝 函数类型的数据
new Promise((resolve, reject) => {
setTimeout(() => {
//30% 1-100 1 2 30
//获取从1 - 100的一个随机数
let n = rand(1, 100);
//判断
if (n <= 30) {
resolve(n); // 将 promise 对象的状态设置为 『成功』
} else {
reject(n); // 将 promise 对象的状态设置为 『失败』
}
}, 1000);
}).then((value) => {
alert('恭喜恭喜, 奖品为 10万 RMB 劳斯莱斯优惠券, 您的中奖数字为 ' + value);
}, (reason) => {
alert('再接再厉, 您的号码为 ' + reason);
});
});
1.1.3 Promise讲解
promise的构造函数
-
Promise的构造函数的参数是一个函数,改函数有2个值resolve, reject;
-
resolve:异步任务成功时候的回调函数,调用后将 promise 对象的状态设置为 『成功』;
-
reject:异步任务失败时候的回调函数,调用后将 promise 对象的状态设置为 『失败』;
then()方法
-
then()方法的作用是Promise实例添加解决(fulfillment)和拒绝(rejection)状态的回调函数。then()方法会返回一个新的Promise实例,所以then()方法后面可以继续跟另一个then()方法进行链式调用。
-
then()方法有2个参数,这2个参数都接收函数参数,第一个参数是解决(fulfillment)状态的回调函数,另外一个参数是拒绝(rejection)状态的回调函数。
小结
-
promise的构造函数是同步执行
-
promise.then中的函数是异步执行
2.实践练习之fs模块&node运行js脚本
fs是Node.js下面对文件进行操作的一个模块,Node.js 提供一组类似 UNIX(POSIX)标准的文件操作 API。 Node 导入文件系统模块(fs)。Node.js 文件系统(fs 模块)模块中的方法均有异步和同步版本,例如读取文件内容的函数有异步的 fs.readFile() 和同步的 fs.readFileSync()。异步的方法函数最后一个参数为回调函数,回调函数的第一个参数包含了错误信息(error)。最好使用异步方法,比起同步,异步方法性能更高,速度更快,而且没有阻塞(重点)。对于流量较大的服务器,最好还是采用异步操作,同步操作时,只有前一个操作结束,才会开始后一个操作,如果某个操作特别耗时(常常发生在读写数据时),会导致整个程序停顿。
1.1回调函数形式
准备工作:准备一个文本文件,待会会读取其中内容
content.txt
观书有感
作者:朱熹
半亩方塘一鉴开,天光云影共徘徊。
问渠那得清如许?为有源头活水来
2-Promise实践练习-fs模块.js
// 声明fs模块
const fs = require('fs');
//回调函数 形式
fs.readFile('./promise/resource/content.txt', (err, data) => {
// 如果出错 则抛出错误
if (err) {
throw err
} else {
//输出文件内容
console.log(data.toString());
}
});
1.2Promise形式
2-Promise实践练习-fs模块.js
// 声明fs模块
const fs = require('fs');
//Promise 形式
new Promise((resolve, reject) => {
fs.readFile('./promise/resource/content.txt', (err, data) => {
//如果出错 失败和成功的回调函数只会执行一个。
if (err) reject(err);
//如果成功
resolve(data);
});
}).then(value => {
// 如果成功,打印txt文件的内容
console.log(value.toString());
}, reason => {
// 如果成功,打印失败的原因
console.log(reason);
3.Promise实践练习Ajax请求
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
.pro{
width: 300px;
margin: 50px auto;
}
button {
padding: 2px;
font-size: 10px;
border: 1px solid lightblue;
color: #000;
}
</style>
</head>
<body>
<div class="pro">
<h4>promise实践操作-ajax请求</h4>
<button id="btn">点击发送ajax</button>
</div>
<script>
// 获取btn按钮
const btn = document.querySelector("#btn")
// 注册点击事件
btn.addEventListener('click',function () {
//promise对象
const p = new Promise((reslove,reject) => {
// 1.创建对象
const xhr = new XMLHttpRequest()
// 2.初始化
xhr.open('GET','https://api.apiopen.top/getJoke')
// 3.发送
xhr.send()
// 4.处理响应结果
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
// 判断响应状态码
if(xhr.status >=200 && xhr.status <300){
// 控制台输出响应体
reslove(xhr.response)
}
// 控制台输出状态码
reject(xhr.status)
}
}
})
// 调用p.then()
p.then(value => {
console.log(value);
},reason => {
console.log(reason);
})
})
</script>
</body>
</html>
4.Promise封装练习-fs模块
/**
* 封装一个函数 mineReadFile 读取文件内容
* 参数: path 文件路径
* 返回: promise 对象
*/
function mineReadFile(path){
return new Promise((resolve, reject) => {
//读取文件
require('fs').readFile(path, (err, data) =>{
//判断
if(err) reject(err);
//成功
resolve(data);
});
});
}
mineReadFile('./promise/resource/content.txt').then(value=>{
//输出文件内容
console.log(value.toString());
}, reason=>{
console.log(reason);
});
5.util.promisify()方法
/**
* util.promisify 方法
*/
//引入 util 模块
const util = require('util');
//引入 fs 模块
const fs = require('fs');
//返回一个新的Promise对象
let mineReadFile = util.promisify(fs.readFile);
mineReadFile('./promise/resource/content.txt').then(value => {
console.log(value.toString());
}, reason => {
console.warn(reason);
});
6.Promise封装AJAX操作
<script>
// 接口地址:http://poetry.apiopen.top/sentences (随机获取一句诗词)
// 新建一个Promise对象
const Pro = new Promise((resolve, reject) => {
// 1.创建对象
const xhr = new XMLHttpRequest();
// 2.初始化,设置请求方式和接口地址
xhr.open("GET", "http://poetry.apiopen.top/sentences");
// 3.发送请求
xhr.send();
// 4.绑定事件,处理响应结果
xhr.onreadystatechange = function () {
// 判断
if (xhr.readyState === 4) {
// 判断响应状态码 200~299
if (xhr.status >= 200 && xhr.status < 300) {
// 获取成功
resolve(xhr.response);
// console.log(xhr.response);
} else {
// 获取失败
reject(xhr.status);
// console.log(xhr.status);
}
}
}
});
// 处理状态
Pro.then((value) => {
console.log("成功:", value);
}, (reason) => {
console.log("失败:", reason);
})
</script>