异步处理模式
promise的用法
const pro = new Promise((resolve, reject)=>{
// 未决阶段的处理
// 通过调用resolve函数将Promise推向已决阶段的resolved状态
// 通过调用reject函数将Promise推向已决阶段的rejected状态
// resolve和reject均可以传递最多一个参数,表示推向状态的数据
})
pro.then(data=>{
//这是thenable函数,如果当前的Promise已经是resolved状态,该函数会立即执行
//如果当前是未决阶段,则会加入到作业队列,等待到达resolved状态后执行
//data为状态数据
}, err=>{
//这是catchable函数,如果当前的Promise已经是rejected状态,该函数会立即执行
//如果当前是未决阶段,则会加入到作业队列,等待到达rejected状态后执行
//err为状态数据
})
未决阶段的处理函数是同步的,会立即执行
thenable和catchable函数是异步的,就算是立即执行,也会加入到事件队列中等待执行,并且,加入的队列是微队列
pro.then可以只添加thenable函数,pro.catch可以单独添加catchable函数
在未决阶段的处理函数中,如果发生未捕获的错误,会将状态推向rejected,并会被catchable捕获
一旦状态推向了已决阶段,无法再对状态做任何更改
Promise并没有消除回调,只是让回调变得可控
**
案例
ajax
function ajax(option) {
return new Promise((resolve, reject) => {
var xhr = null;
if (window.XMLHttpRequest) {
xhr = new window.XMLHttpRequest;
} else if (window.ActiveXObject("Microsoft.XMLHttp")) {
xhr = new window.ActiveXObject("Microsoft.XMLHttp");
} else {
alert('浏览器不支持访问数据')
}
var method = '';
var deta = '';
var url = option.url;
var isAync = typeof option.isAync === 'undefined' ? true : option.isAync;
var success = typeof option.success === 'function' ? option.success : function () {};
// 判断请求方式 如果是小写将其改为大写
if (option.method) {
method = option.method.toUpperCase();
} else {
method = 'GET'
}
// 判断请求参数,并将对象类型的参数修改为字符串
if (typeof option.deta === 'object') {
for (var prop in option.deta) {
deta += prop + '=' + option.deta[prop] + '&';
}
} else {
deta = option.data;
}
//是否为get
if (option.option === 'GET') {
// 请求数据
xhr.open(method, url + '?' + deta, isAync);
xhr.send();
} else {
// 此处为post
xhr.open(method, url, isAync)
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencode'); //以字符串的形式
xhr.send()
}
// 判断是否请求成功
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
// success(JSON.parse(xhr.responseText))
resolve(JSON.parse(xhr.responseText))
}else{
reject(xhr.status)
}
}
}
})
}
const pro = ajax({
url:'./data/students.json?name=李华'
})
//pro: resolved
pro.then(data => {
console.log(data);
}, err => {
console.log(err)
})
案例二
function love(girl) {
return new Promise((resolve, reject) => {
console.log(`邓哥向女神【${girl}】发出短信`)
setTimeout(() => {
if (Math.random() < 0.1) {
resolve(true)
} else {
reject(false)
}
}, 100);
})
}
const pro = love(1)
//pro: resolved
pro.then(data => {
console.log(data);
}, err => {
console.log(err)
})
//也可写成
//pro: resolved
pro.then(data => {
console.log(data)
})
pro.catch(err => {
console.log(err)
})
案例二
function love(girl) {
return new Promise((resolve, reject) => {
console.log(`邓哥向女神【${girl}】发出短信`)
setTimeout(() => {
if (Math.random() < 0.1) {
resolve(true)
} else {
resolve(false)
}
}, 0);
})
}
let por;
for (let i = 0; i < 20; i++) {
if(i == 0){
por = love(i)
}
por = por.then(value =>{
if(value ){
console.log(`女神【${i}】回复啦短信`)
}else{
console.log(`女神【${i}】没有回复啦短信`)
}
if(i < 19){
return love(i + 1);
}
})
}
回调地狱的代码
function love(girl ,callback){
console.log(`邓哥向女神【${girl}】发出短信`)
setTimeout(() => {
if(Math.random()<0.1){
callback(true)
}else{
callback(false)
}
}, 100);
}
for(let i = 0 ; i < 3 ; i++){
love(i+1,result =>{
if(result){
console.log(`女神【${i+1}】回复啦短信`)
}else{
console.log(`女神【${i+1}】没有回复啦短信`)
}
})
}