promise fetch axios

本文探讨了基于Promise的Ajax请求实现,包括发送顺序控制、错误处理、Fetch API的HTTP请求、参数传递,以及axios的简化用法。同时讲解了async/await的运用,使异步代码更易读。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

promise fetch axios

基于Promise发送Ajax

// 路由
app.get('/data', (req, res) => {
  res.send('Hello World!')
})
function queryData(url) {
  var p = new Promise(function (resolve, reject) {
    var xhr = new XMLHttpRequest();
    xhr.onreadystatechange = function () {
      if (xhr.readyState != 4) return;
      if (xhr.readyState == 4 && xhr.status == 200) {
        // 处理正常的情况
        resolve(xhr.responseText);
      } else {
        // 处理异常情况
        reject('服务器错误');
      }
    };
    xhr.open('get', url);
    xhr.send(null);
  });
  return p;
}
queryData('http://localhost:3000/data')
  .then(function (data) {
    console.log(data);
  }, function (info) {
    console.log(info)
  });

基于Promise发送Ajax请求解决回调地狱

// 路由
app.get('/data', (req, res) => {
  res.send('Hello World!')
})
app.get('/data1', (req, res) => {
  setTimeout(function () {
    res.send('Hello TOM!')
  }, 1000);
})
app.get('/data2', (req, res) => {
  res.send('Hello JERRY!')
})

............基于Promise发送Ajax...............

// 发送多个ajax请求并且保证顺序
queryData('http://localhost:3000/data')
  .then(function(data){
    console.log(data)
    return queryData('http://localhost:3000/data1');
  })
  .then(function(data){
    console.log(data);
    return queryData('http://localhost:3000/data2');
  })
  .then(function(data){
    console.log(data)
  });

.then参数

............基于Promise发送Ajax...............


queryData('http://localhost:3000/data')
  .then(function(data){
    return queryData('http://localhost:3000/data1');
  })
  .then(function(data){
    return new Promise(function(resolve, reject){
      setTimeout(function(){
        resolve(123);
      },1000)
    });
  })
  .then(function(data){
    console.log(data)  //123
    return 'hello';
  })
  .then(function(data){
    console.log(data) //hello
  })

Promise 基本API

实例方法
.then()
  • 得到异步任务正确的结果
.catch()
  • 获取异常信息
.finally()
  • 成功与否都会执行(不是正式标准
 /*
   Promise常用API-实例方法
 */
 // console.dir(Promise);
 function foo() {
   return new Promise(function (resolve, reject) {
     setTimeout(function () {
       // resolve(123);
       reject('error');
     }, 100);
   })
 }
 foo()
   .then(function (data) {
     console.log(data)   //123
   })
   .catch(function (data) {
     console.log(data)   //error
   })
   .finally(function () {
     console.log('finished')   //finished
   });
   
 // --------------------------
 // 两种写法是等效的
 // foo()
 //   .then(function (data) {
 //     console.log(data)   //123
 //   }, function (data) {
 //     console.log(data)  //error
 //   })
 //   .finally(function () {
 //     console.log('finished') //finished
 //   });
静态方法
.all()
  • Promise.all方法接受一个数组作参数,数组中的对象(p1、p2、p3)均为promise实例(如果不是一个promise,该项会被用Promise.resolve转换为一个promise)。它的状态由这三个promise实例决定
.race()
  • Promise.race方法同样接受一个数组作参数。当p1, p2, p3中有一个实例的状态发生改变(变为fulfilledrejected),p的状态就跟着改变。并把第一个改变状态的promise的返回值,传给p的回调函数
app.get('/a1', (req, res) => {
  setTimeout(function () {
    res.send('Hello TOM!')
  }, 1000);
})
app.get('/a2', (req, res) => {
  setTimeout(function () {
    res.send('Hello JERRY!')
  }, 2000);
})
app.get('/a3', (req, res) => {
  setTimeout(function () {
    res.send('Hello SPIKE!')
  }, 3000);
})
............基于Promise发送Ajax...............
 
 
 var p1 = queryData('http://localhost:3000/a1');
 var p2 = queryData('http://localhost:3000/a2');
 var p3 = queryData('http://localhost:3000/a3');
 
 Promise.all([p1, p2, p3]).then(function (result) {
   console.log(result)  //["Hello TOM!", "Hello JERRY!", "Hello SPIKE!"]
 })
 
 // Promise.race([p1,p2,p3]).then(function(result){
 //   console.log(result)  //Hello TOM!
 // })

fetch API 中的 HTTP 请求

  • fetch(url, options).then()
  • HTTP协议,它给我们提供了很多的方法,如POST,GET,DELETE,UPDATE,PATCH和PUT
    • 默认的是 GET 请求
    • 需要在 options 对象中 指定对应的 method method:请求使用的方法
    • post 和 普通 请求的时候 需要在options 中 设置 请求头 headers 和 body

Fetch API 基本用法

app.get('/fdata', (req, res) => {
  res.send('Hello Fetch!')
})
fetch('http://localhost:3000/fdata').then(function(data){
   // text()方法属于fetchAPI的一部分,它返回一个Promise实例对象,用于获取后台返回的数据
   return data.text();
 }).then(function(data){
   console.log(data);  //Hello Fetch!
 })

Fetch API 调用接口传递参数

后台

// 设置允许跨域访问该服务
app.all('*', function (req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header('Access-Control-Allow-Methods', 'PUT, GET, POST, DELETE, OPTIONS');
  res.header("Access-Control-Allow-Headers", "X-Requested-With,Content-Type,mytoken");
  next();
});
app.get('/books', (req, res) => {
  res.send('传统的URL传递参数!' + req.query.id)
})
app.get('/books/:id', (req, res) => {
  res.send('Restful形式的URL传递参数!' + req.params.id)
})
app.delete('/books/:id', (req, res) => {
  res.send('DELETE请求传递参数!' + req.params.id)
})
app.post('/books', (req, res) => {
  res.send('POST请求传递参数!' + req.body.uname + '---' + req.body.pwd)
})
app.put('/books/:id', (req, res) => {
  res.send('PUT请求传递参数!' + req.params.id + '---' + req.body.uname + '---' + req.body.pwd)
})
    // app.get('/books', (req, res) => {
    //   res.send('传统的URL传递参数!' + req.query.id)
    // })
    // app.get('/books/:id', (req, res) => {
    //   res.send('Restful形式的URL传递参数!' + req.params.id)
    // })
    // app.delete('/books/:id', (req, res) => {
    //   res.send('DELETE请求传递参数!' + req.params.id)
    // })
    // app.post('/books', (req, res) => {
    //   res.send('POST请求传递参数!' + req.body.uname + '---' + req.body.pwd)
    // })
    // app.put('/books/:id', (req, res) => {
    //   res.send('PUT请求传递参数!' + req.params.id + '---' + req.body.uname + '---' + req.body.pwd)
    // })


    // GET参数传递-传统URL
    // fetch('http://localhost:3000/books?id=123', {
    //   method: 'get'
    // })
    //   .then(function (data) {
    //     return data.text();
    //   }).then(function (data) {
    //     console.log(data) //08-FetchAPI参数传递.html:35 传统的URL传递参数!123
    //   });

    // GET参数传递-restful形式的URL
    // fetch('http://localhost:3000/books/456', {
    //   method: 'get'
    // })
    //   .then(function (data) {
    //     return data.text();
    //   }).then(function (data) {
    //     console.log(data)   //Restful形式的URL传递参数!456
    //   });

    // DELETE请求方式参数传递
    // fetch('http://localhost:3000/books/789', {
    //   method: 'delete'
    // })
    //   .then(function (data) {
    //     return data.text();
    //   }).then(function (data) {
    //     console.log(data)   //DELETE请求传递参数!789
    //   });

    // POST请求传参
    // fetch('http://localhost:3000/books', {
    //   method: 'post',
    //   body: 'uname=lisi&pwd=123',
    //   headers: {
    //     'Content-Type': 'application/x-www-form-urlencoded'
    //   }
    // })
    //   .then(function (data) {
    //     return data.text();
    //   }).then(function (data) {
    //     console.log(data)  //POST请求传递参数!lisi---123
    //   });

    // POST请求传参   有问题将跨域拦截写到一行上
    // fetch('http://localhost:3000/books', {
    //   method: 'post',
    //   body: JSON.stringify({
    //     uname: '张三',
    //     pwd: '456'
    //   }),
    //   headers: {
    //     'Content-Type': 'application/json'
    //   }
    // })
    //   .then(function (data) {
    //     return data.text();
    //   }).then(function (data) {
    //     console.log(data)    //POST请求传递参数!张三---456
    //   });

    // // PUT请求传参
    fetch('http://localhost:3000/books/123', {
      method: 'put',
      body: JSON.stringify({
        uname: '张三',
        pwd: '789'
      }),
      headers: {
        'Content-Type': 'application/json'
      }
    })
      .then(function (data) {
        return data.text();
      }).then(function (data) {
        console.log(data) //PUT请求传递参数!123---张三---789
      });

Fetch响应结果的数据格式

app.get('/json', (req, res) => {
  res.json({
    uname: 'lisi',
    age: 13,
    gender: 'male'
  });
})
fetch('http://localhost:3000/json').then(function(data){
  // return data.json();
  return data.text();
}).then(function(data){
  // console.log(data.uname)
  // console.log(typeof data)
  var obj = JSON.parse(data);
  console.log(obj.uname,obj.age,obj.gender)  //lisi 13 male
})

axios基本使用

基本使用

app.get('/adata', (req, res) => {
  res.send('Hello axios!')
})
 axios.get('http://localhost:3000/adata').then(function (ret) {
   // 注意data属性是固定的用法,用于获取后台的实际数据
   console.log(ret.data)   //Hello axios!
   console.log(ret)
 })

axios请求参数

后台

app.get('/axios', (req, res) => {
  res.send('axios get 传递参数' + req.query.id)
})
app.get('/axios/:id', (req, res) => {
  res.send('axios get (Restful) 传递参数' + req.params.id)
})
app.delete('/axios', (req, res) => {
  res.send('axios get 传递参数' + req.query.id)
})
app.post('/axios', (req, res) => {
  res.send('axios post 传递参数' + req.body.uname + '---' + req.body.pwd)
})
app.put('/axios/:id', (req, res) => {
  res.send('axios put 传递参数' + req.params.id + '---' + req.body.uname + '---' + req.body.pwd)
})
    // axios get请求传参
    // axios.get('http://localhost:3000/axios?id=123').then(function (ret) {
    //   console.log(ret.data)   //axios get 传递参数123
    // })

    // axios.get('http://localhost:3000/axios/123').then(function (ret) {
    //   console.log(ret.data)   //axios get (Restful) 传递参数123
    // })
    // axios.get('http://localhost:3000/axios', {
    //   params: {
    //     id: 789 
    //   }
    // }).then(function (ret) {
    //   console.log(ret.data)   //axios get 传递参数789
    // })

    // axios delete 请求传参
    // axios.delete('http://localhost:3000/axios', {
    //   params: {
    //     id: 111
    //   }
    // }).then(function (ret) {
    //   console.log(ret.data)   //axios get 传递参数111
    // })

    // axios.post('http://localhost:3000/axios', {
    //   uname: 'lisi',
    //   pwd: 123
    // }).then(function (ret) {
    //   console.log(ret.data) //axios post 传递参数lisi---123
    // })
    // var params = new URLSearchParams();
    // params.append('uname', 'zhangsan');
    // params.append('pwd', '111');
    // axios.post('http://localhost:3000/axios', params).then(function (ret) {
    //   console.log(ret.data)   //axios post 传递参数zhangsan---111
    // })

    // axios put 请求传参
    axios.put('http://localhost:3000/axios/123', {
      uname: 'lisi',
      pwd: 123
    }).then(function (ret) {
      console.log(ret.data)   //axios put 传递参数123---lisi---123
    })

axios 响应结果与全局配置

app.get('/axios-json', (req, res) => {
  res.json({
    uname: 'lisi',
    age: 12
  });
})
axios.get('http://localhost:3000/axios-json').then(function (ret) {
      console.log(ret.data.uname)   //LISI
    })


    // 配置请求的基准URL地址
    axios.defaults.baseURL = 'http://localhost:3000/';
    // 配置请求头信息
    axios.defaults.headers['mytoken'] = 'hello';
    axios.get('axios-json').then(function (ret) {
      console.log(ret.data.uname)   //LISI
    })

axios拦截器

	# 1. 请求拦截器 
	axios.interceptors.request.use(function(config) {
      console.log(config.url)	//http://localhost:3000/adata
      # 1.1  任何请求都会经过这一步   在发送请求之前做些什么   
      config.headers.mytoken = 'nihao';
      # 1.2  这里一定要return   否则配置不成功  
      return config;
    }, function(err){
       #1.3 对请求错误做点什么    
      console.log(err)
    })
	#2. 响应拦截器 
    axios.interceptors.response.use(function(res) {
      #2.1  在接收响应做些什么  
      var data = res.data;
      return data;
    }, function(err){
      #2.2 对响应错误做点什么  
      console.log(err)
    })

async 和 await

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-r2U01Ysw-1622355023575)(C:\Users\Shinelon\AppData\Roaming\Typora\typora-user-images\1619175098660.png)]

  • async作为一个关键字放到函数前面
    • 任何一个async函数都会隐式返回一个promise
  • await关键字只能在使用async定义的函数中使用
    • ​ await后面可以直接跟一个 Promise实例对象
    • ​ await函数不能单独使用
  • async/await 让异步代码看起来、表现起来更像同步代码
 	# 1.  async 基础用法
    # 1.1 async作为一个关键字放到函数前面
	async function queryData() {
      # 1.2 await关键字只能在使用async定义的函数中使用      await后面可以直接跟一个 Promise实例对象
      var ret = await new Promise(function(resolve, reject){
        setTimeout(function(){
          resolve('nihao')
        },1000);
      })
      // console.log(ret.data)
      return ret;
    }
	# 1.3 任何一个async函数都会隐式返回一个promise   我们可以使用then 进行链式编程
    queryData().then(function(data){
      console.log(data)
    })

	#2.  async    函数处理多个异步函数
    axios.defaults.baseURL = 'http://localhost:3000';

    async function queryData() {
      # 2.1  添加await之后 当前的await 返回结果之后才会执行后面的代码   
      
      var info = await axios.get('async1');
      #2.2  让异步代码看起来、表现起来更像同步代码
      var ret = await axios.get('async2?info=' + info.data);
      return ret.data;
    }

    queryData().then(function(data){
      console.log(data)
    })

)
return ret;
}
# 1.3 任何一个async函数都会隐式返回一个promise 我们可以使用then 进行链式编程
queryData().then(function(data){
console.log(data)
})

#2.  async    函数处理多个异步函数
axios.defaults.baseURL = 'http://localhost:3000';

async function queryData() {
  # 2.1  添加await之后 当前的await 返回结果之后才会执行后面的代码   
  
  var info = await axios.get('async1');
  #2.2  让异步代码看起来、表现起来更像同步代码
  var ret = await axios.get('async2?info=' + info.data);
  return ret.data;
}

queryData().then(function(data){
  console.log(data)
})

### 
<think>好的,用户想了解在使用axios时如何处理异步操作和Promise。首先,我需要回忆一下axios的基本用法和它与Promise的关系。记得axios是基于Promise的HTTP客户端,所以它返回的是Promise对象,这意味着可以用.then()和.catch()来处理异步操作。 接下来,用户可能需要具体的例子,所以应该分步骤说明。首先是基本用法,展示如何用.then()处理响应,用.catch()处理错误。然后,可能需要更现代的async/await语法,这样代码更简洁。这里要注意说明async函数的使用,以及如何在try/catch块中捕获错误。 然后,用户可能想知道如何同时处理多个请求,比如使用Promise.all()来并行发送请求,并处理所有结果。这时候需要给出一个例子,比如同时获取用户数据和帖子数据,然后处理两者的结果。 接下来,可能需要讨论错误处理的细节,比如如何区分不同的错误类型,比如网络错误和HTTP状态码错误。还要提到取消请求的方法,比如使用CancelToken,这在需要取消重复或过时的请求时很有用。 还要考虑用户可能遇到的常见问题,比如在异步操作中如何处理顺序请求,也就是一个请求完成后发另一个请求的例子。这时候用async/await会更清晰。 最后,需要总结最佳实践,比如推荐使用async/await提高可读性,正确处理错误,取消不必要的请求,以及处理多个请求的方法。同时,要确保引用相关的资料,比如引用[1]关于async函数返回Promise的内容,引用[2]提到的Async函数简化代码的部分,以及引用[3]中的资源操作例子,可能和HTTP请求相关。 检查是否有遗漏的要点,比如axios的配置、拦截器,但用户的问题集中在异步处理和Promise,所以可能不需要深入拦截器的内容。确保示例代码正确,语法正确,比如使用模板字符串,箭头函数等。同时,注意用中文回答,符合用户要求的结构,分步骤和代码示例,最后生成相关问题。 现在组织内容,确保每个部分清晰,并且引用正确的位置。比如在讨论async函数时引用[^1],在错误处理部分提到使用Async.Rejected的简化方法引用[^2],在资源请求部分可能引用[^3]的例子,但axios和$resource不同,所以可能只在需要的时候引用。React的引用[^4]可能不太相关,可以忽略。 最后生成相关问题,考虑用户可能进一步的问题,比如错误处理的最佳实践、取消请求的方法、async/await的优势,以及多个请求的处理,确保问题覆盖用户可能的兴趣点。</think>### 如何在使用axios时处理异步操作和Promise #### 1. **理解axiosPromise的关系** axios是一个基于Promise的HTTP客户端,所有axios请求默认返回Promise对象。因此,可以通过Promise链式调用(`.then()`、`.catch()`)或`async/await`语法处理异步操作。 #### 2. **基本用法:Promise链式调用** ```javascript axios.get('https://api.example.com/data') .then(response => { console.log('请求成功:', response.data); }) .catch(error => { console.error('请求失败:', error); }); ``` #### 3. **使用async/await简化代码** 通过`async`函数包裹异步操作,用`await`等待Promise解决: ```javascript async function fetchData() { try { const response = await axios.get('https://api.example.com/data'); console.log('数据获取成功:', response.data); } catch (error) { console.error('错误:', error); } } fetchData(); ``` 异步函数返回Promise的特性与axios的兼容性良好[^1]。 #### 4. **并行处理多个请求** 使用`Promise.all()`并行执行多个请求: ```javascript async function fetchMultipleData() { try { const [userData, posts] = await Promise.all([ axios.get('https://api.example.com/user'), axios.get('https://api.example.com/posts') ]); console.log('用户数据:', userData.data, '帖子:', posts.data); } catch (error) { console.error('至少一个请求失败:', error); } } ``` #### 5. **错误处理细化** - **区分错误类型**: 检查错误是否为axios生成的`AxiosError`: ```javascript .catch(error => { if (axios.isAxiosError(error)) { console.log('HTTP错误状态码:', error.response?.status); } else { console.log('非HTTP错误:', error); } }); ``` - **全局错误拦截**: 通过axios拦截器统一处理错误: ```javascript axios.interceptors.response.use( response => response, error => { console.error('拦截到错误:', error); return Promise.reject(error); } ); ``` #### 6. **取消请求** 使用`CancelToken`或`AbortController`(Axios >=0.22.0)取消请求: ```javascript const controller = new AbortController(); axios.get('https://api.example.com/data', { signal: controller.signal }) .then(response => { /* ... */ }) .catch(error => { if (axios.isCancel(error)) { console.log('请求被取消:', error.message); } }); // 触发取消 controller.abort('用户取消了操作'); ``` #### 7. **顺序请求示例** 若需按顺序发送请求(如先获取用户ID,再获取用户详情): ```javascript async function sequentialRequests() { const userIdResponse = await axios.get('/api/user-id'); const userDetail = await axios.get(`/api/user/${userIdResponse.data.id}`); console.log('用户详情:', userDetail.data); } ``` ### 最佳实践总结 1. **优先使用async/await**:提高代码可读性,减少嵌套[^2]。 2. **统一错误处理**:通过拦截器或`try/catch`集中管理错误。 3. **合理取消请求**:避免无效请求占用资源。 4. **并行与顺序结合**:根据场景选择`Promise.all`或顺序`await`。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值