Promise、async/await和Promise封装ajax

本文介绍了JavaScript中的Promise对象,其用于解决异步编程问题,包括Promise的状态、构造函数、then/catch方法的使用以及async/await语法的应用,还展示了如何封装AJAX请求并结合Promise进行操作。
摘要由CSDN通过智能技术生成

Promise使用

在JavaScript的世界中,所有代码都是单线程执行的。由于这个“缺陷”,导致JavaScript的所有网络操作,浏览器事件,都必须是异步执行。异步执行可以用回调函数实现.

Promise是ES6中引入的一个异步编程解决方案,与传统的ES5方法相比它的结构更合理,功能更强大.

特点

Promise对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态.

语法:

  var p = new Promise(function(resolve,reject){})
 resolve 代表 决定(成功); reject 代表 失败
使用
基本使用
    const p  = new Promise(function(resolve,reject){
        setTimeout(function(){
           // resolve('我是成功的')
           reject('这是失败的');
        },2000)
    });

.then(callback)的使用(成功时调用)

.catch(callback)的用法(失败时调用)

  p.then(function(data){
			console.log('resolved成功回调');
			console.log('成功回调接受的值:',data);
		}).catch(function(reason, data){
		    console.log('catch到rejected失败回调');
		     console.log('catch失败执行回调抛出失败原因:',reason);
	});	
效果和写在then的第二个参数里面一样。它将大于10的情况下的失败回调的原因输出

注意:resolve和reject的两种状态

resolve作用是,将Promise对象的状态从“未完成”变为“成功”(即从 pending 变为 resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;
reject作用是,将Promise对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。
工作中常用方式,结合函数

我们用Promise的时候一般是包在一个函数中,在需要的时候去运行这个函数

 let promiseFn =()=>{
	 console.log('点击方法被调用')
	 let p = new Promise(function(resolve, reject){
		//做一些异步操作
		setTimeout(function(){
				console.log('执行完成Promise');
				resolve('成功的时候调用');
			}, 2000);
		});
        return p
	}

promiseFn().then(function(data){
     console.log(11111)
}).catch(function(data){
     console.log(2222)
})
promise改造ajax依赖调用

使用promise检测ajax的请求状态,利用promise的成功状态函数,返回ajax请求到的数据

第一步,将ajax进行封装

    const ajaxParam=param=>{
        return new Promise(function(resolve,reject){
            let xhr = new XMLHttpRequest();
        
              xhr.open('get',param.url); // 默认是true,表示异步
      
              
              xhr.onreadystatechange = function(){
                  if(xhr.readyState==4 ){
                      if(xhr.status==200){
                          resolve(xhr.responseText)
                      }else{
                          reject()
                      }

                  }
              }
             xhr.send();
        });
    }

第二步:使用then和catch获取结果,

ajaxPromise({type:'get', url:'http//:www.baidu.com',data:null})
.then(function(data){

}).catch(function(data){

});

扩展:
Promise.all()

所有的异步请求完成才执行的方法.

Promise.all在处理多个异步处理时非常有用,比如说一个页面上需要等两个或多个ajax的数据回来以后才正常显示,在此之前只显示loading图标。

let wake = (time) => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(`${time / 1000}秒后醒来`)
    }, time)
  })
}

let p1 = wake(3000);
let p2 = wake(2000);

Promise.all([p1, p2]).then((result) => {
  console.log(result)       // [ '3秒后醒来', '2秒后醒来' ]
}).catch((error) => {
  console.log(error)
})
只有两次调用promise都执行完毕,才会执行all
Promise.race()

Promse.race就是赛跑的意思,意思就是说,Promise.race([p1, p2, p3])里面哪个结果获得的快,就返回那个结果,不管结果本身是成功状态还是失败状态。

let p1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('success')
  },1000)
})

let p2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject('failed')
  }, 500)
})

Promise.race([p1, p2]).then((result) => {
  console.log(result)
}).catch((error) => {
  console.log(error)  // 打开的是 'failed'
})

ASYNC/AWAIT

  • async/await 是一个 es7 的语法

  • 这个语法是 回调地狱的终极解决方案

  • 语法:

    async function fn() {
      const res = await promise对象
    }
    
  • 这个是一个特殊的函数方式

  • 可以 await 一个 promise 对象

  • 可以把异步代码写的看起来像同步代码

代码如下:

/*
            pAjax({url: 'http://localhost:2305/user/test1'})
            .then(data=>{
                return get({url: 'http://localhost:2305/user/test2', params: {a: data}})
            })
            .then(data=>{
                return pAjax({url: 'http://localhost:2305/user/test3', params: {b: data}})
            })
            .then(data=>{
                console.log(data)
            })
        */
        // 这种方式比直接使用Promise更为优雅
        async function request(){
            // 可以把异步代码写的看起来像同步代码
            let data1 = await get({url: 'http://localhost:2305/user/test1'})
            console.log(data1)

            let data2 = await get({url: 'http://localhost:2305/user/test2', params: {a: data1}})
            console.log(data2)
            
            let data3 = await pAjax({url: 'http://localhost:2305/user/test3', params: {b: data2}})
            console.log(data3)
        }
        request()

附件

封装的ajax请求.js源码

@params : 对象,第一个值是url 第二个值是传入的参数,以对象形式书写。

@return : 返回接受的数据

// get请求方式
function ajax_get(options){
    let xhr = new XMLHttpRequest()
    if(options.params){
        let str = '?'
        for(let key in options.params){
            str += `${key}=${options.params[key]}`
            str += '&'
        }
        str = str.slice(0, -1)
        xhr.open('get', options.url+str)
    }else{
        xhr.open('get', options.url)
    }
    xhr.onreadystatechange = ()=>{
        if(xhr.readyState == 4){
            if(xhr.status == 200){
                options.success && options.success(xhr.responseText)
            }else{
                options.error && options.error()
            }
        }
    }
    xhr.send()
}
// post请求方式
function ajax_post(options){
    let xhr = new XMLHttpRequest()
    xhr.open('post', options.url)
    xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded')
    xhr.onreadystatechange = ()=>{
        if(xhr.readyState == 4){
            if(xhr.status == 200){
                options.success && options.success(xhr.responseText)
            }else{
                options.error && options.error()
            }
        }
    }
    if(options.params){
        let str = ''
        for(let key in options.params){
            str += `${key}=${options.params[key]}`
            str += '&'
        }
        str = str.slice(0, -1)
        xhr.send(str)
    }else{
        xhr.send()
    }
}
// Promise版本ajax
function get(options){
    return new Promise((resolve, reject)=>{
        let xhr = new XMLHttpRequest()
        if(options.params){
            let str = '?'
            for(let key in options.params){
                str += `${key}=${options.params[key]}`
                str += '&'
            }
            str = str.slice(0, -1)
            xhr.open('get', options.url+str)
        }else{
            xhr.open('get', options.url)
        }
        xhr.onreadystatechange = ()=>{
            if(xhr.readyState == 4){
                if(xhr.status == 200){
                    resolve(xhr.responseText)
                }else{
                    reject()
                }
            }
        }
        xhr.send()
    })
}

function post(options){
    return new Promise((resolve, reject)=>{
        let xhr = new XMLHttpRequest()
        xhr.open('post', options.url)
        xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded')
        xhr.onreadystatechange = ()=>{
            if(xhr.readyState == 4){
                if(xhr.status == 200){
                    resolve(xhr.responseText)
                }else{
                    reject()
                }
            }
        }
        if(options.params){
            let str = ''
            for(let key in options.params){
                str += `${key}=${options.params[key]}`
                str += '&'
            }
            str = str.slice(0, -1)
            xhr.send(str)
        }else{
            xhr.send()
        }
    })
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值