一、同步和异步思想
在软件世界中,
同步任务:当一个操作开始执行后,主程序等待它执行完成,才能继续向下执行;
异步任务:当一个操作开始执行后,主程序无需等待它执行完成,就可以继续向下执行,此操作与主程序同时(并发)执行。
二、回调函数
1.一个函数中以形参形式调用另一个函数,被调用的函数就称回调函数
2.作用:常用于解决异步编程问题
3.常用两种写法
//方式一
function c1(){
console.log('我是回调函数');
}
function a(c1) {
c1()
}
//方式二:匿名函数方式
function a(function (){
console.log('我是回调函数');
})
案例:简要封装[Ajax]
js:
const router=require("./router.js")
router.get("/ajax1",function(req,res){
res.end('{"name":"karen","age":20}')
})
router.get("/ajax2",function(req,res){
res.end('{"name":"jack","age":22}')
})
html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script>
function myjq(url,cb){
var xhr=new XMLHttpRequest()
xhr.open("GET",url,true)
xhr.send()
xhr.onreadystatechange=function(){
if(xhr.readyState==4&&xhr.status==200){
cb(xhr.responseText)
}
}
}
</script>
</head>
<body>
<button onclick="fn()">ajax1</button>
<script>
function fn(){
console.log(11112)
//用ajax的工具函数请求url
var url="http://192.168.6.60:8080/ajax1"
myjq(url,function(data){
console.log(data)
})
}
</script>
<button onclick="fn2()">ajax2</button>
<script>
function fn2(){
var url2="http://192.168.6.60:8080/ajax2"
myjq(url2,(data)=>{
console.log(data)
})
}
</script>
</body>
</html>
1.promise是ES6提供的一个解决异步编程的对象,包含异步操作的结果(成功、失败)
2.作用:①实现异步编程;
②用于替代回调函数,解决回调函数嵌套问题--(回调地狱)。
3.promise对象的特点: ①对象的状态不受外界影响;promise对象只有三种状态:pending(进行中)、fulfilled(已成功)、rejected(已失败)。
②promise对象一旦改变状态就不会再变,任何时候都可以得到这个结果;
状态改变只有两种可能:
由pending改变为fulfilled、由pending改变为rejected;
只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果,这时就称为 resolved(已定型)。
首先得了解promise的用法和实用意义:
对象的状态不受外界影响。Promise 对象代表一个异步操作,有三种状态: 1.pending: 初始状态,不是成功或失败状态。 2.fulfilled: 意味着操作成功完成。 3.rejected: 意味着操作失败。 只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。这也是 Promise 这个名字的由来,它的英语意思就是「承诺」,表示其他手段无法改变。
一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise 对象的状态改变,只有两种可能:从 Pending 变为 Resolved 和从 Pending 变为 Rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果。就算改变已经发生了,你再对 Promise 对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。
有了 Promise 对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。此外,Promise 对象提供统一的接口,使得控制异步操作更加容易
案例:用promise简单实现Ajax的封装
<script>
function myaxios (url) {
var p1=new Promise(function(n1,n2){
var xhr=new XMLHttpRequest()
xhr.open("GET",url,true)
xhr.send()
xhr.onreadystatechange=function(){
if(xhr.readyState==4&&xhr.status==200){
n1(xhr.responseText)
}else if(xhr.readyState==4&&xhr.status==404){
n2(xhr.responseText)
}
}
// n1(200)
})
return p1
}
</script>
<button onclick="fn()">ajax1</button>
<script>
function fn(){
var url="http://192.168.6.60:8080/ajax1"
myaxios(url).then((res)=>{
console.log(res,1111)
})
}
</script>
案例:
function ajaxPromise(position) {
// 1. 创建AJAX核心对象
const xhr = new window.XMLHttpRequest
//创建一个新的Promise对象
return new Promise((resolve, reject) =>{
//resolve存储响应成功数据,reject存储响应失败数据
//get请求
if (position.method.toUpperCase() == 'GET') {
// 2. 建立连接
xhr.open('GET', position.url + '?' + formateParme(position.data))
xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded')
// 3.发送请求
xhr.send()
} else if (position.method.toUpperCase() == 'POST') { //post请求
// 2. 建立连接
xhr.open('POST', position.url)
xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded')
// 3.发送请求
xhr.send(formateParme(position.data))
}
//4.处理响应结果
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
resolve(xhr.responseText)
}else{
reject('网络出错'+xhr.status)
}
}
}
})
}
function formateParme(data) {
let arr = []
for (const key in data) {
let item = `${key}=${data[key]}` // username=admin ,password=123
arr.push(item) //[username=admin,password=123]
}
return arr.join('&')
}
调用
ajaxPromise({
//参数
method: 'post',
url: 'http://10.7.171.124:8088/api/login',
data: {
username: usernameInput.value,
password: passwordInput.value
}
}).then(success=>{
//处理响应结果
let data =JSON.parse(success)
if (data.resultCode == -1) {
alert('用户名或密码出错')
} else {
alert('登录成功')
// 跳转到主界面
location.href = 'index.html'
}
})