Promise、async/await和Promise封装ajax

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()
        }
    })
}


  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: Promise 封装 Ajax 是一种常见的异步编程方式,可以通过 Promise 对象来处理 Ajax 请求的成功和失败。具体实现方式可以参考以下代码: ``` function ajax(url, method, data) { return new Promise(function(resolve, reject) { var xhr = new XMLHttpRequest(); xhr.open(method, url, true); xhr.onreadystatechange = function() { if (xhr.readyState === 4) { if (xhr.status === 200) { resolve(xhr.responseText); } else { reject(xhr.statusText); } } }; xhr.onerror = function() { reject(xhr.statusText); }; xhr.send(data); }); } ``` 使用时可以这样调用: ``` ajax('/api/data', 'GET') .then(function(response) { console.log(response); }) .catch(function(error) { console.error(error); }); ``` 这样就可以通过 Promise 封装 Ajax 请求,实现更加优雅的异步编程。 ### 回答2: Promise是一种用于处理异步操作的封装工具,它可以帮助我们更好地管理和处理异步任务。而Ajax是一种用于实现前端与后端数据交互的技术,通过发送HTTP请求来获取数据并在页面上进行展示。 将Promise封装Ajax可以带来以下好处: 1.简化代码:传统的Ajax代码往往会包含大量的回调函数,逻辑复杂且难以维护。使用Promise封装Ajax可以将异步操作分离出来,并以一种更加直观和一致的方式处理异步任务,使代码更加简洁明了。 2.提高可读性:Promise提供了then和catch等方法来处理异步任务的成功和失败,可以将异步操作的处理逻辑写在链式调用中,使代码的逻辑更加清晰易懂。 3.异常处理:通过Promise的catch方法,可以捕获到异步任务中的异常并进行统一的处理,避免异常被控制流终止。 下面是一个使用Promise封装Ajax的示例代码: ```javascript function ajax(url, method, data) { return new Promise(function(resolve, reject) { var xhr = new XMLHttpRequest(); xhr.open(method, url, true); xhr.onreadystatechange = function() { if (xhr.readyState === 4) { if (xhr.status === 200) { resolve(xhr.responseText); } else { reject(new Error(xhr.statusText)); } } }; xhr.send(data); }); } ajax('http://example.com/api', 'GET') .then(function(response) { console.log('请求成功:', response); }) .catch(function(error) { console.log('请求失败:', error); }); ``` 以上代码中,ajax函数接受三个参数:url、method和data,通过XMLHttpRequest发送请求,并根据响应状态码进行相应的处理。使用Promise的resolve和reject来处理请求成功和失败的情况,以便后续链式调用then和catch进行处理。这样就可以更加方便地管理和处理Ajax请求了。 ### 回答3: 封装PromiseAjax请求可以提供更加简洁和可读性高的代码,同时能够更好地处理异步操作和错误处理。下面是一个示例代码: ```javascript function ajax(url) { return new Promise((resolve, reject) => { const xhr = new XMLHttpRequest(); xhr.open('GET', url); xhr.onload = function() { if (xhr.status === 200) { resolve(xhr.response); } else { reject(new Error(xhr.statusText)); } }; xhr.onerror = function() { reject(new Error('Network Error')); }; xhr.send(); }); } // 调用封装Ajax请求 ajax('https://api.example.com/data') .then(response => { console.log(response); }) .catch(error => { console.error(error); }); ``` 以上代码中,我们创建了一个`ajax`函数来封装Ajax请求。该函数接受一个URL参数,并返回一个Promise对象。在函数内部,我们使用`XMLHttpRequest`对象来发送HTTP请求,并在请求完成后处理响应和错误。 当请求成功响应时,我们调用`resolve`函数将响应作为参数传递给Promise对象的`then`方法中的回调函数,从而能够在调用`ajax`函数后链式调用`then`方法获取响应数据。 当请求出现错误时,无论是网络错误还是HTTP状态码错误,我们都调用`reject`函数将错误信息作为参数传递给Promise对象的`catch`方法中的回调函数,在调用`ajax`函数后可以链式调用`catch`方法捕获错误并进行错误处理。 通过封装PromiseAjax请求,我们能够更加清晰地处理异步操作和错误处理,提高代码的可读性和可维护性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值