Promise基本操作
一.什么是Promise
- 抽象表达:
1) Promise 是一门新的技术(ES6 规范)
2) Promise 是 JS 中进行异步编程的新解决方案
备注:旧方案是单纯使用回调函数 - 具体表达:
1)从语法上来说: Promise 是一个构造函数
2)从功能上来说: promise 对象用来封装一个异步操作并可以获取其成功/失败的结果值。
二.为什么使用Promise
1.promise使用回调函数更灵活。旧的回调函数必须在启动异步任务前指定。
2.promise:启动异步任务 => 返回promise对象 => 给promise对象绑定回调函数(甚至能在异步任务结束后指定多个)。
3.promise支持链式调用,可以解决回调地狱问题。(回调地狱就是多层回调函数嵌套使用,就是套娃,这样就不利于阅读和异常处理。)
三.Promise的状态改变:
promise状态表示实例对象的一个属性【PromiseState】。包括以下值:
(1)pending 未决定的
(2)resolved 或 fullfilled 成功
(3)rejected 失败
Promise对象的值表示实例对象的另一个属性【PromiseResult】。保存着对象【成功/失败】的结果。而其状态改变只有以下两种可能:
(1)pending 变为resolved
(2)pending 变为 rejected
注:一个promise对象只能改变一次,无论成功或失败都会有一个结果数据,成功的称为 value , 失败的称为 reason 。
四.Promise基本流程图:
五.Promise初体验
效果:设计一个抽奖程序,随机1-100之间的数,点击按钮后小于等于30则为中奖,否则不中奖。
<button id="btn">点击进行抽奖</button>
<script>
function rand(n, m) {
return Math.ceil(Math.random() * (n - m) + m);
}
//传统JS的写法
let btn = document.querySelector('#btn');
// btn.addEventListener('click', function () {
// setTimeout(function () {
// let n = rand(100, 1);
// console.log(n);
// if (n <= 30) {
// alert("恭喜你中奖了!")
// } else {
// alert("谢谢惠顾!")
// }
// }, 1000)
// })
//Promise写法
btn.addEventListener('click', function () {
let pro = new Promise(function (resolve, reject) { //resolve解决 reject拒绝
setTimeout(() => {
let n = rand(100, 1);
console.log(n);
if (n <= 30) {
resolve(n); //成功 ()中可将值传到then中
} else {
reject(n); //失败
}
})
});
pro.then(
(resolve) => {
alert("恭喜你中奖了!" + "数字是" + resolve)
},
(reject) => { //resone 理由
alert("谢谢惠顾!" + "数字是" + reject)
}
);
});
</script>
六.fs操作
const fs = require('fs');
// //回调函数形式
// fs.readFile('./commet/1.txt', (err, data) => {
// //如果出错 抛出错误
// if (err) throw err;
// console.log(data.toString());
// })
//promise形式
const pro = new Promise((resolve, reject) => {
fs.readFile('../commet/1.txt', (err, data) => {
if (err) reject();
resolve(data.toString());
});
});
pro.then(
(data) => {
console.log(data);
},
(err) => {
console.log(err);
}
);
七.Promise发送ajax请求
<button id="btn">点击发送ajax请求</button>
<script>
const btn = document.querySelector('button');
btn.addEventListener('click', () => {
const pro = new Promise((resolve, reject) => {
let xhr = new XMLHttpRequest();
xhr.open('GET', 'http://127.0.0.1:8000/server');
xhr.send();
xhr.onreadystatechange = () => {
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.status < 300) {
resolve(xhr.response);
} else {
reject(xhr.status);
}
}
}
});
pro.then(
(resolve) => {
console.log(resolve);
},
(reject) => {
console.log(reject);
}
);
});
</script>
八.Promise封装fs
//使用promise封装fs 以后使用可以直接调用
function minReadfile(path) {
const pro = new Promise((resolve, reject) => {
const fs = require('fs');
fs.readFile(path, (err, data) => {
if (err) reject(err);
resolve(data);
});
});
return pro;
}
minReadfile('..commet/1.txt').then
(
resolve => {
console.log(resolve.toString());
},
reject => {
console.log(reject);
}
);
九.util.promisify封装fs
// util模块中的promisift方法
//引入util模块
const util = require('util');
//引入fs模块
const fs = require('fs');
//返回一个新的函数 不用进行封装了
let minReadfile = util.promisify(fs.readFile);
minReadfile('../commet/1.txt').then(
resolve => {
console.log(resolve.toString());
}
)
十.Promise封装ajax
<script>
function sendajax(url) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.send();
xhr.onreadystatechange = () => {
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.status < 300) {
resolve(xhr.response);
} else {
reject(err);
}
}
}
});
}
sendajax('http://127.0.0.1:8000/server').then(
(resolve) => {
console.log(resolve.toString());
},
(reject) => {
console.log(reject);
}
);
</script>