ES6 promise 封装http请求

 今天研究了一下同事封装的http请求,用的是promise。

 大结构是:

 const __fetch = (url, data = {}, config = {}) => {
        let params = Object.assign({}, data);
        config.headers = Object.assign({}, config.headers, { "Content-Type": "application/json", "Access-Control-Allow-Origin": "*" });
        config.body = JSON.stringify(params)
        return Promise.race([
            fetch(url, config),
            new Promise((resolve, reject) => {
                setTimeout(() => reject({ code: '504', msg: '请求超时' }), config.timeout || 20000)
            })
        ]).then(response => {
            if (response.status != 200) {
                return Promise.reject({ code: response.status, msg: '请求失败' })
            }
            return response.json()
        }, error => {
            if (error && error.code) {
                return Promise.reject(error)
            }
        }).then(response => new Promise((resolve, reject) => {
            if (response & response.code && response.code === '000') {
                resolve(response.data)
            } else {
                reject(response)
            }
        })).catch((e) => {
            if (!e || !e.code) return Promise.reject({ code: '999' })
            if (parseInt(e.code) === 998) return Promise.reject(e)
            return Promise.reject({ code: e.code })
        })
    }
  }  

 const post=(url,data={},config={})=>{
    config.method='POST'
    return __fetch(url,data,config)
 }  

 

知识点:

1.fetch()

 此处可与axios做一个对比

 axios需要npm install   本质上是对XHR的封装

 fetch不需要npm install  ES6本身就支持 直接使用(前提:浏览器支持es6语法)即可 不是对XHR的封装

 但是两者都是基于Promise实现的。

axios({
    method: 'post',
    url: '/user/12345',
    data: {
        firstName: 'Fred',
        lastName: 'Flintstone'
    }
}).then(function (response) {
    console.log(response);
}).catch(function (error) {
    console.log(error);
});

 

多说一下:async/await

async 用于声明一个function是异步的,返回一个Promise对象

await可以认为是async wait的简写,表示等待一个一步方法执行完成

async-await是寄生于Promise,Generator的语法糖

try {
  let response = await fetch(url);  //await在这里表示等待promise返回结果 再继续执行
  let data = response.json();
  console.log(data);
} catch(e) {
  console.log("Oops, error", e);
}

 

最后说 fetch

  fetch(url,options)

  options中第一个参数是设置请求方法(默认是get)

  第二个参数是设置头部(一般是json,所以设置为application/json)第三个参数是设置包含json内容的主体

fetch('some-url',{
       method:'post',
      headers:{'Content-Type':'application/json'},
      body:JSON.stringify(content)
     }).then(response=>response.json())  //response.json()是返回另一个promise
        .then(data=>console.log(data))
        .catch(error=>console.log(error))

 

2.Promise.race()=>多个异步任务是为了容错

Promise是一个容器,里面保存着未来某个时间点才会结束的操作。

由于fetch暂不支持超时控制,造成了流量的浪费,因此在这里使用Promise.race()对两个promise请求合并。

执行两个异步任务,一个去真实请求,一个超时报错,哪个先返回 获取哪个。

另外一个会继续执行,但是结果会被丢弃

 

3.job1.then(job2).then(job3).catch(handleError)

  有若干个异步任务,需要先做任务1,如果成功后再做任务2,如果成功后再做任务3

  任何任务失败则不再继续 并执行错误处理函数。

  当promise被明确拒绝,会发生拒绝,但是如果在构造函数回调中引发的错误,会隐式拒绝,因此promise链的尾部必须有个catch接着

  之所以需要用两个then,是因为fetch方法不关心ajax是否成功,只关心从服务器发送请求和接受响应。

  因此第一个then是看ajax是否成功,第二个then是看具体的错误是什么,因为只有response.json.status才知道具体的错误。

 

posted @ 2019-04-17 19:38  Artimis  阅读(1832)  评论(0编辑  收藏  举报