promise
用promise对函数封装:
原来的代码:
<!DOCTYPE html>
<html>
<head>
<title>vue demo</title>
<style type="text/css">
body {
font: 1.2em arial, helvetica, sans-serif;
margin-top: 50px;
margin-left:500px;
color: #bb00ff;
}
</style>
</head>
<body>
<div id="app">
<button id="btn">点击抽奖</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script type="text/javascript">
function rand (m, n) {
return Math.ceil(Math.random() * (n - m + 1)) + m - 1
}
const btn = document.querySelector('#btn')
// 绑定单击事件
btn.addEventListener('click', function () {
// 定时器
setTimeout(() => {
// /30%1-100123
// 获取从1-100的一个随机数
let n = rand(1, 100)
// 判断
if (n < 30) {
alert('恭喜恭喜,奖品为10万RMB劳斯莱斯优惠券')
} else {
alert('再接再厉') }
}, 1000)
}
)
</script>
</body>
</html>
用promise进行封装:
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script> Vue.config.productionTip = false</script>
<script type="text/javascript">
function rand (m, n) {
return Math.ceil(Math.random() * (n - m + 1)) + m - 1
}
const btn = document.querySelector('#btn');
// 绑定单击事件
btn.addEventListener('click', function ()
{
//promise实现
const p = new Promise(
(resolve,reject) => {
setTimeout(()=>{
//promise可以包裹一个异步操作
let n = rand(1, 100);
if(n < 30){
resolve();// resolve()可以将promise对象状态设置为成功
} else{
reject();
},1000);
});
p.then(()=>{
console.log('ok');
},()=>{
console.log('fail');
alert('again');}
)
});
</script>
用promise进行读取文件函数封装:
mineReadfine (path) {
return new Promise((resolve, reject) => {
require('fs').readFile(path, (err, data) => {
if (err) reject(err)
resolve(data)
})
})
}
mineReadfine('name.txt').then({
value=>{
console.log(value.toString());
},reason=> {
console.log(reason)
}
})
promise·fs模块
什么是fs模块 ==> File System
fs模块是Node.js的一个核心模块,专门用来操作系统中的文件,常用的操作方式是对文件的读取和写入使用require(‘fs’)载入fs模块,模块中所有方法都有同步和异步两种形式。异步方法中回调函数的第一个参数总是留给异常参数(exception),如果方法成功完成,该参数为null或undefined。异步写法demo:有一个回调函数。
fs.readFile(文件路径,options,回调函数)
异步的读取指定路径的文件,回调函数在读取文件完成后触发
readFileSync方法的第一个参数是文件路径,第二个参数可以是一个表示配置的对象,也可以是一个表示文本文件编码的字符串
const fs = require('fs');
fs.readFile('name.txt',(err,data)=>{
if(err) throw err;
console.log(data.toString());
});
promise封装Ajax请求
/
**
封装一个函数 sendAJAX发送 GET AJAX请求
*参数RL
*返回结果Promise对象
*/
function sendAJAX(){
return new Promise((resolve, reject)=>
const xhr = new xmlhttprequest();
xhr.responseType ='json';
xhr.open("GET", url);
xhr.send();
∥处理结果
xhr. onreadystatechange= function(){
if(xhr. readystate =4){
∥/判断成功
if(xhr. status>=2e&&xhr.status<30e)
∥/成功的结果
resolve(xhr. response);
}else{
reject(xhr. status);}
}
}
}
});
}
sendAJAX("https: api. apiopen. top/getok')
.then(value =>{
console. log(value);
} reason =>
console.warn(reason);
});
. promise的状态改变和对象的值
实例对象中的一个属性PromiseState
pending未决定的
resolved 成功
rejected 失败
- pending变为 resolved
- pending变为 rejected
说明:只有这2种,且一个 promise对象只能改变一次
无论变为成功还是失败,都会有一个结果数据
成功的结果数据一般称为 value,失败的结果数据一般称为 reason
实例对象中的另一个属性PromiseResult 保存着对象成功/失败的结果
通过resolve和reject函数可以改变
resolve reject方法
先看resolve:
<script type="text/javascript">
let p=Promise. resolve(521);
//如果传入的参数为非Promise类型的对象则返回的结果为成功 promise对象
//如果传入的参数为 Promise对象,则参数的结果决定了 resolve的结果
let p2 = Promise.resolve(new Promise((resolve,reject)=>{
resolve('OK');
// reject('Error');
}))
console. log(p2);
p2.catch(reason=>{
console. log(reason);
})
</script>
如果运行:
let p2 = Promise.resolve(new Promise((resolve,reject)=>{
reject(‘Error’);
}))
reject:(不管参数是什么返回的对象状态都是失败)
<script type="text/javascript">
let p=Promise. reject(521);
console.log(p);
</script>
.all方法:
let p1 = new Promise((resolve, reject)=>{
resolve('OK');
}
)
let p2 =Promise.resolve('Success');
let p3 =Promise.resolve('Oh Yeah');
const result= Promise.all([p1,p2,p3]);
console.log(result);
返回一个数组,且只有三个对象都为成功状态时数组才为成功状态
then方法的返回结果是一个promise对象
3.改变promise状态和指定调函数谁先谁后?
(1)都有可能,正常情况下是先指定调再改变状态,但也可以先改状态再指定回调
2如何先改状态再指定回调?
①在执行器中直接调用 resolve/reject
②延迟更长时间才调用then
(3)什么时候才能得到数据?
①如果先指定的回调,那当状态发生改变时,回调函数就会调用,得到数据
如果先改变的状态,那当指定回调时,回调函数就会调用,得到数据
4. promise.then()返回的新 promise的结果状态由什么决定?
(1)简单表达:由then指定的回调函数执行的结果决定
(2)详细表达:
①如果抛出异常,新 promise变为 rejected, reason为抛出的异常
②如果返回的是 promise的任意值,新 promise变为 resolved value为返回的值
③如果返回的是另一个新 promise,此 promise的结果就会成为新 promise的结果
5. promise如何串连多个操作任务?
(1) promise的then返回一个新的 promise,可以开成then的链式调用
(2)通过then的链式调用串连多个同步/异步任务
回调函数
回调函数就是一个函数,它是在我们启动一个异步任务的时候就告诉它:等你完成了这个任务之后要干什么。这样一来主线程几乎不用关心异步任务的状态了,他自己会善始善终。
实例
function print() {
document.getElementById("demo").innerHTML="RUNOOB!";
}
setTimeout(print, 3000);
这段程序中的 setTimeout 就是一个消耗时间较长(3 秒)的过程,它的第一个参数是个回调函数,第二个参数是毫秒数,这个函数执行之后会产生一个子线程,子线程会等待 3 秒,然后执行回调函数 “print”
回调函数的执行时间:状态改变的时候才会执行。
中断promise链的方法:用return new Promise(()=>{})
resolve reject 抛出异常 都会改变对象状态
ajax请求服务器(使用express框架)
先安装express:
清空缓存:npm cache clean -f
安装express: cnpm i express
新建ajax.js:
const express = require('express')
// eslint-disable-next-line no-unused-vars
// 创建应用对象
// eslint-disable-next-line no-unused-vars
const appp = express()
appp.get('/', (request, response) => {
response.send('hello')
})
appp.listen(8081, () => {
console.log('begin..')
})
终端输入:
node ajax.js
结果:
响应报文的内容:
标头:
模拟发送请求并得到服务器的数据:
新建html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
#result{
margin-top: 100px;
width: 200px;
height: 100px;
border: solid 1px #FFA722;
}
</style>
</head>
<body>
<button>发送请求</button>
<div id = "result">
<br>
</div>
</body>
<script type="text/javascript">
const btn = document.getElementsByTagName('button')[0]// 获取button元素
btn.onclick = function () {
// 创建对象
const xhr = new XMLHttpRequest()
// 初始化 设置请求方法和URL
xhr.open('GET', 'http://localhost:8082/')
xhr.send()
// 事件绑定,处理服务端返回的结果
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
// 状态为4时才表示内容已经全部返回
if (xhr.status >= 200 && xhr.status < 300) {
console.log(xhr.status)// 状态码
console.log(xhr.statusText)// 状态字符串
console.log(xhr.getAllResponseHeaders())// 所有响应头
console.log(xhr.response)// 响应体
}
}
}
}
</script>
</html>
ajax.js:
const express = require('express')
// eslint-disable-next-line no-unused-vars
// 创建应用对象
// eslint-disable-next-line no-unused-vars
const appp = express()
appp.get('/', (request, response) => {
// 设置响应头,设置允许跨域
response.setHeader('Access-Control-Allow-Origin','*')
response.send('hello r353 i am ajax')
})
appp.listen(8082, () => {
console.log('begin..')
})
request:是对请求报文的封装
response: 对响应报文的封装
注意:
response.setHeader(‘Access-Control-Allow-Origin’,’*’)这句话中的Access-Control-Allow-Origin不能换成其他东西,否则xhr状态码一直是0
加上:
const result = document.querySelector('#result')
result.innerHTML = xhr.response
再点击按钮:
控制台:
超时设置:
xhr.timeout=2000 两秒内如果还没有结果发送过来就取消请求
超时回调:
xhr.ontimeout = function(){
alert(‘网络异常,稍后重试’)
}
用axios发送ajax请求:
<button>GET</button>
<button>POST</button>
<button>AJAX</button>
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.js"></script>
<script type="text/javascript">
const btns = document.getElementsByTagName('button')// 获取button元素
btns[0].onclick = function () {
axios.get('http://localhost:8083/server', {
params: {
id: 100,
name: 'ds'
}
})
}
</script>