promise是一种很强大灵活方便的异步编程解决方案。
promise接受一个函数作为参数,这个函数接受两个参数,resovle方法和reject方法。
resovle方法用于将promise的状态从未完成设置为成功,通常就是在异步请求成功的时候,调用该方法。
resolve方法用于将promise的状态从未完成设置为失败。通常就是在异步请求失败的时候调用该方法。
1、
const p = new Promise((resolve,reject) => {
let xhr = new XMLHttpRequest();
xhr.open("GET","http://119.29.25.147/php.php",true);
xhr.responseType = "json";
xhr.setRequestHeader("Accept","application/json");
xhr.onreadystatechange = function () {
if (this.readyState !== 4) {
return;
}
if (this.status === 200) {
resolve(this.response) //成功
}else {
reject(this.status);//失败
}
}
xhr.send();
})
上述代码中,我们新建了promise对象,在异步请求成功的时候,调用resolve方法,并将响应数据作为参数传递。
如果失败,则调用reject方法,并将状态文本进行传递。
接下来,我们需要通过promise的then方法设置当promise的状态为成功或失败时将执行的回调函数。
p.then((res) => {
console.log(res) //响应文本信息
}).catch((res) => {
console.log(res)//状态码
})
当然promise的状态为成功的时候,then方法中的回调函数会被调用,否则直接跳过,不被调用。
回调函数中可以接受resolve方法传递过来的参数。
promise的then方法会返回另一个promise对象,所以可以使用链式调用。可以看到,在then方法后面使用了catch方法,catch方法用于捕获错误。当promise的状态为失败,或者运行中出现的错误,catch方法都能够捕获到。它也可以捕获前面的then方法中的错误,所以,catch方法应该在最后调用,以便能够捕获前面的错误。当错误被捕获或者为失败状态的时候,catch方法中的回调会被调用,否则不被调用。
这种处理异步结果的方式,很好地将异步流程代码和处理结果的代码分离出来。
第一个then方法在执行完毕后会将返回值作为参数传递给下一个then方法。如下:
var p = new Promise((reslove,reject) => {
reslove("请求成功");
})
p.then((res) => {
return res + "200"
}).then((res) => {
console.log(res) //请求成功200
})
当前一个then的回调函数返回的是promise对象的时候,下一个then方法的回调会等待这个promise对象的状态发生改变的时候才执行。如下:
function c () {
return new Promise((reslove,reject) => {
setTimeout(() => {
reslove("异步请求第三阶段执行完毕");
},1000)
})
}
function b () {
return new Promise((reslove,reject) => {
setTimeout(() => {
console.log("异步请求第二阶段执行完毕");
reslove();
},1000)
})
}
var a = new Promise((reslove,reject) => {
setTimeout(() => {
console.log("异步请求第一阶段执行完毕");
reslove();
},1000)
})
a.then(b).then(c).then((res) => {
console.log(res)
})
结果:
异步请求第一阶段执行完毕
异步请求第二阶段执行完毕
异步请求第三阶段执行完毕
promise这种串联执行异步任务的方式好多了
Promise.all方法可处理多个异步任务。
all方法接受一个数组,数组中的每个成员需要是一个promise。它们将按照传入的顺序执行。
当数组中的每个promise的状态为成功的时候,promise对象的状态才为成功。否则,如果数组中的一个promise成员为失败状态,那么promise的状态也将为失败。第一个失败的promise实例的返回值,会传递给promise的回调函数。
function c () {
return new Promise((reslove,reject) => {
setTimeout(() => {
console.log(3)
reslove("第三发炮弹");
},3000)
})
}
function b () {
return new Promise((reslove,reject) => {
setTimeout(() => {
console.log(2)
reslove("第二发炮弹");
},2000)
})
}
function a () {
return new Promise((reslove,reject) => {
setTimeout(() => {
console.log(1)
reslove("第一发炮弹");
},1000)
})
}
Promise.all([a(),b(),c()]).then((res) => {
console.log(res);//["第一发炮弹", "第二发炮弹", "第三发炮弹"]
})
Promise.race() 方法。
race方法与all方法的使用方法一样,但表现不同的是,只要数组中的某个promise率先改变状态,promise的状态也会跟着改变。率先改变状态的promise的返回值为传递给promise的回调函数。其他的promise的返回值不会被接收。
function c () {
return new Promise((reslove,reject) => {
setTimeout(() => {
reslove("第三发炮弹");
},3000)
})
}
function b () {
return new Promise((reslove,reject) => {
setTimeout(() => {
reslove("第二发炮弹");
},2000)
})
}
function a () {
return new Promise((reslove,reject) => {
setTimeout(() => {
reslove("第一发炮弹");
},1000)
})
}
Promise.race([a(),b(),c()]).then(res => {
console.log(res) // 第一发炮弹
})