Promise介绍
Promise 是异步编程的一种更优雅的解决方案,比传统的解决方案——回调函数——更合理和更强大。简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。
简单理解为: promise是对异步操作的封装,封装异步文件读写,定时器、ajax异步网络请求...
语法: ES6新增一个对象
作用: 对异步任务进行封装,更好的更优雅的处理异步任务结果 回调函数
ajax({
success:function(data){}
})
setTimout(function(){
},1000)
使用:
let promise = new Promise(function(resolve,reject){
// resolve 函数 处理异步任务成功的结果 resolve('成功')
// reject 函数 处理异步任务失败的结果 reject('失败')
// 异步任务封装
setTimeout(function(){
if(true){
resolve('成功')
} else {
reject('失败')
}
},1000)
})
promise.then(function(result){
result=>成功
})
promise.catch(function(error){
error=>失败
})
基本用法
异步ajax封装
**
*promise 对ajax异步网络请求封装
*创建promise对象,封装具体异步操作
*/
const promise = new Promise(function (resoloved,rejected){
// 1. XmlHttpRequest
// 2. open()建立连接
// 3. send()发送请求
//4.处理响应
//1.实例XMLHttpRequest对象
let xhr = new window. XMLHttpRequest()
//2.建立连接
xhr.open( 'GET',"http://10.7.176.118:8089/ api/list')
//3.发送请求
xhr.send()
//4.处理响应数据
xhr.onreadystatechange = function (e) {
e = e ll window. event
target = e.target ll e.srcElementif (target.readyState == 4) {
//响应成功
if (target.status == 200){
resoloved(target.responseText)
}else{
rejected('网络出错')
}
}
}
})
Promise链式调用
要读取三个文件,第一个文件读取完成后,再读取第二个文件,然后再是第三个文件。这时引起 回调函数层层嵌套问题,回调地狱,其实就是回调函数嵌套过多导致的
promise解决回调嵌套问题
new Promise(function (resolve, reject) {
ajax({
url:'第一个请求',
success (res) {
resolve(res)
}
})
}).then(function (res) {
//准备发送第二个请求
return new Promise(function (resolve, reject) {
ajax({
url:'第二个请求" ,
data: {a:res.a, b:res.b},
success (res) {
resolve(res)
}
})
})
}).then(function (res) {
ajax ({
url: '第三个请求',
data: {a: res.a, b: res.b},
success (res) {
console.log(res)
}
})
})
promise封装ajax
/**
* 封装一个函数获取promsie对象, promise对象封装处理网络请求异步任务
options = {
method:'get',
url:''
data:{}
}
* @param {*} options
* @returns
*/
function myPromise(options) {
return new Promise((resolve, reject) => {
jax({
method: options.method,
url: options.url,
data: options.data,
success: function (result) {
resolve(result)
},
fail:function(error){
reject(error)
}
})
})
}
function ajax(options) {
// 1. 创建XMLHttpRequest
let xhr = new XMLHttpRequest()
let param = formateParam(options.data) // name=jack&age=18
let method = options.method.toUpperCase()
// 2. 建立连接
if (method == 'GET') {
xhr.open(options.method, options.url + '?' + param)
// 3. 发送请求
xhr.send()
} else if(method == 'POST'){
xhr.open(options.method,options.url)
xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded')
xhr.send(param)
}
// 4. 接收响应数据
xhr.onreadystatechange = function () {
// 4.1 是否响应完成
if (xhr.readyState === 4) {
// 4.2 是否成功响应
if (xhr.status === 200) {
let data = xhr.responseText // 响应内容
data = JSON.parse(data)
options.success(data)
} else {
// alert('网络出错 ' + xhr.status)
options.fail('网络出错 ' + xhr.status)
}
}
}
}
/**
* 格式化参数
* {name:'jack',age:18} => name=jack&age=18
* 遍历对象,属性转换成名称=值形式,存储到数组, 再将数组元素用&符号拼接join('&)
* ['name=jack','age=18'] ->
*/
function formateParam(obj) {
let arr = []
for (const key in obj) {
let item = `${key}=${obj[key]}` // name=jack age=18
arr.push(item) // ['name=jack','age=18;]
}
return arr.join('&') // name=jack&age=18
}
Promise方法
-
Promise.resolve方法
var p = Promise.resolve('Hello'); p.then(function (s) { console.log(s) }); // Hello
上面代码生成一个新的Promise对象的实例p,它的状态为fulfilled,所以回调函数会立即执行,Promise.resolve方法的参数就是回调函数的参数。
如果Promise.resolve方法的参数是一个Promise对象的实例,则会被原封不动地返回。
-
Promise.reject方法
var p = Promise.reject('出错了'); p.then(null, function (s) { console.log(s) }); //出错了
Promise.reject(reason)方法也会返回一个新的Promise实例,该实例的状态为rejected。
Promise.reject方法的参数reason,会被传递给实例的回调函数。
-
Promise.race
//竞争执行谁执行,先返回谁结果 Promise.race([promise1,promise2]).then(data => { console.log(data); }) -
Promise.all
//同时并发执行,返回数组形式结果 Promise.all([promise1,promise2]).then(datas => { console.log(datas); })