ES6-promise实现异步请求

一、Promise是什么

  简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。

      ES6规定,Promise对象是一个构造函数,用来生成Promise实例。Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolvereject,这两个参数都是函数

new Promise(function(resolve,reject){
  异步操作 ajax 定时器等{
    if(结果满意)
      resolve(value)
    else
      reject(error)
  }
})

二、then方法

     Promise 实例生成以后,可以用then 方法分别指定resolve和reject的回调函数。then方法可以接受两个回调函数作为参数。第一个回调函数是Promise对象的状态变为resolved时调用,第二个回调函数是Promise对象的状态变为rejected时调用。其中,第二个函数是可选的,不一定要提供 。这两个函数都接受Promise 对象传出的值作为参数。

function timeout(ms) {
  return new Promise((resolve, reject) => {
    if(ms>=100)
     setTimeout(resolve, ms, 'done'); //setTimeout的第三个参数用于给第一个参数(函数)传参
    else
     setTimeout(reject, ms, 'error'); //setTimeout的第三个参数用于给第一个参数(函数)传参
  });
}
timeout(100).then((value) => {
  console.log(value);  //done
},(error)=>{
  console.log(error)
});
timeout(100).then((value) => {
  console.log(value);
},(error)=>{
  console.log(error)  //error
});

三、promise中 的catch()方法 

  • catch方法用于指定发生错误时的回调
timeout(100).then((value) => {
  console.log(value);  
}.catch((error)=>{
  console.log(error)
});
  • catch可以检测resolve中抛出的异常
timeout(100).then((value) => {
  console.log(value);
  console.log(somethingUndefined)
}).catch((error)=>{
  console.log(error)  //somethingUndefined is not defined
});//如果resolve中发生异常,JS不会报错,而会把错误抛给catch的第一个参数

四、Promise手动封装ajax函数

<script>
       // ajax函数默认的参数
       let ajaxDefaultOptions = {
           url: '#', // 请求地址,默认为空
           method: 'GET', // 请求方式,默认为GET请求
           async: true, // 请求同步还是异步,默认异步
           timeout: 0, // 请求的超时时间
           dataType: 'text', // 请求的数据格式,默认为text
           data: null, // 请求的参数,默认为空
           headers: {}, // 请求头,默认为空
           onprogress: function () {}, // 从服务器下载数据的回调
           onuploadprogress: function () {}, // 处理上传文件到服务器的回调
           xhr: null // 允许函数外部创建xhr传入,但是必须不能是使用过的
       };

       function _ajax(paramOptions) {
          //将传入的参数和默认值合并
let options
= {}; for (const key in ajaxDefaultOptions) { options[key] = ajaxDefaultOptions[key]; } // 如果传入的是否异步与默认值相同,就使用默认值,否则使用传入的参数 options.async = paramOptions.async === ajaxDefaultOptions.async ? ajaxDefaultOptions.async : paramOptions.async; // 判断传入的method是否为GET或者POST,否则传入GET 或者可将判断写在promise内部,reject出去 options.method = paramOptions.method ? ("GET" || "POST") : "GET"; // 如果外部传入xhr,否则创建一个 let xhr = options.xhr || new XMLHttpRequest(); // return promise对象 return new Promise(function (resolve, reject) { xhr.open(options.method, options.url, options.async); xhr.timeout = options.timeout; // 设置请求头 for (const key in options.headers) { xhr.setRequestHeader(key, options.headers[key]); } // 注册xhr对象事件 xhr.responseType = options.dataType;

//从服务器上下载数据每50ms触发一次 xhr.onprogress
= options.onprogress; xhr.onuploadprogress = options.onuploadprogress; // 开始注册事件 // onloadend:请求结束,无论成功或者失败 xhr.onloadend = function () { if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) { resolve(xhr); } else { reject({ errorType: "status_error", xhr: xhr }); } }; // 请求超时 xhr.ontimeout = function () { reject({ errorType: "timeout_error", xhr: xhr }); }
// ,服务器异常,请求错误 xhr.onerror = function () { reject({ errorType: "onerror", xhr: xhr }); }
// abort错误(未明白,只知道是三种异常中的一种) xhr.onabort = function () { reject({ errorType: "onabort", xhr: xhr }); }
// 捕获异常 try { xhr.send(options.data); } catch (error) { reject({ errorType: "send_error", error: error }); } }); } // 调用示例 _ajax({ url: 'http://localhost:3000/suc', async: true, onprogress: function (evt) { console.log(evt.position / evt.total); }, dataType: 'text/json' }).then( function (xhr) { console.log(xhr.response); }, function (e) { console.log(JSON.stringify(e)) }); </script>

参考文章:

https://blog.csdn.net/dkr380205984/article/details/81303171

阮一峰:https://blog.csdn.net/bangbanggangan/article/details/81102052

https://www.cnblogs.com/kazetotori/p/6037940.html

https://blog.csdn.net/weixin_42614080/article/details/90762439

https://blog.csdn.net/qq_38796823/article/details/88209426

原文地址:https://www.cnblogs.com/qing-5/p/11364200.html