axios 和 PromiseA+

axios 基於promise封裝的ajax庫 用於客戶端發送ajax請求

  1. 安裝axios 庫 npm i axios --save/yarn add axios--save

axios經常使用方法

####git請求 axios.get(url,config) 返回promise對象css

axios.get('/api/get_aside',{
    params:{
        aside_id:1
    }
}).then(({data})=>bindHTML(data));
複製代碼

post 請求

axios.post(url,data); 返回promise對象 能夠使用.then then回調的形參reshtml

  • res 是一個通過axios封裝過的對象 其中包含了http的顯影狀態 響應狀態碼等信息
  • 對象中的data屬性值纔是咱們請求來的數據
  • console.log(res);
  • console.log(res.data)
axios.post('api/get_aside',{aside_id:1,name:'xyz'}).then(function(res){
   // res 是一個通過axios封裝過的對象,其中包含了http的響應狀態,響應狀態碼等信息;
  // 對象中的data屬性值纔是咱們請求來的數據
  // console.log(res);
  // console.log(res.data);
  bindHTML(res.data);  
})
複製代碼

併發多個請求 且要等全部的請求以後再作處理

axios.all([axios請求1,axios請求2,....]) 仍然返回then 可是then方法要傳入axios.spread(callback)ios

axios.all([getUser(1), getAside(1)]).then(axios.spread((user, aside) => {
  console.log(user);
  console.log(aside);
複製代碼

ajax接口 返回靜態資源文件 如html css js 圖片的服務稱爲靜態資源服務 而ajax接口通常根據客戶端的請求返回具體的內容;

增長ajax接口

  • 如何區分ajax接口仍是靜態資源服務請求? 靜態資源文件請求通常包含文件的擴展名,特殊的有 / ,因此若是pathname有擴展名或者是 / 就是靜態資源服務,不然就是接口;
  • 全部的ajax接口返回json,設置內容類型爲 application/json;
  • 設置返回json的編碼爲 charset=UTF-8; 若是不設置返回的json會亂碼;
let http = require('http');
let fs = require('fs');
let url = require('url');
let mime = require('mime');

let server = http.createServer((req, res) => {

  let {method} = req;
  let urlObj = url.parse(req.url, true);
  let {pathname} = urlObj;

  let filePath = '';
  let contentType = '';

  // 1. 靜態資源服務
  if (pathname === '/' || /(\.\w+)$/.test(pathname)) {
    if (pathname === '/') {
      filePath = __dirname + '/index.html';
      contentType = 'text/html';
    } else {
      filePath = __dirname + pathname;
      contentType = mime.getType(pathname);
    }

    fs.readFile(filePath, (err, data) => {
      if (err) {
        res.statusCode = 404;
        res.end(`${pathname} You are looking for is not found`);
      } else {
        res.setHeader('Content-Type', contentType);
        res.end(data);
      }
    })


  } else {
    // ajax 接口
    res.setHeader('Content-Type', 'application/json;charset=UTF-8;');
    if (pathname === '/api/get_aside') {
      // 使用data和end事件獲取post請求的數據

      if (method.toUpperCase === 'POST') {
        var postStr = '';
        req.on('data', (data) => postStr += data);
        req.on('end', () => {
          let obj = JSON.parse(postStr);
          fs.readFile(__dirname + '/aside.json', (err, data) => {
            if (err) {
              res.statusCode = 404;
              res.end(`${pathname} You are looking for is not found`);
            } else {
              res.setHeader('Content-Type', 'application/json;charset=UTF-8;');
              res.end(data);
            }
          });
        });
      } else {
        fs.readFile(__dirname + '/aside.json', (err, data) => {
          if (err) {
            res.statusCode = 404;
            res.end(`${pathname} You are looking for is not found`);
          } else {
            res.end(data);
          }
        });
      }
    }

    // 獲取用戶的信息
    if (pathname === '/api/get_user') {
      let urlObj = url.parse(req.url, true);
      let {u_id} = urlObj.query;
      fs.readFile(__dirname + '/user.json', 'utf8', function (err, data) {
        let dataArr = JSON.parse(data);
        let user = dataArr.find(item => +item.id === +u_id);
        if (user) {

          res.end(JSON.stringify({
            code: 0,
            data: {
              token: 'adsflkds1fldslafk'
            },
            msg: 'ok'
          }))
        } else {
          res.end(JSON.stringify({
            code: -1,
            data: {},
            msg: '用戶不存在'
          }))
        }
      })
    }
  }

});

server.listen(8000, () => console.log('port 8000 is on'));
複製代碼

PromiseA+

實現一個promise

class MyPromise{
    constructor(executor){
     // this 是當前類的實例
    // 當resolve執行時,會把當前實例上成功的事件池中的全部函數挨個執行
    // 給實例添加兩個事件池,一個是裝成功的事件函數,一個裝失敗的事件函數
    // 初始化一個狀態 pending
    // 初始化一個值value   
    this.state = 'pending';
    this.fulfilledEvent = [];
    this.rejectedEvent = [];
    this.value = undefined;
    
    let resolve = (result)=>{
        //循環事件池中的函數 讓其挨個執行
        //循環狀態 一旦狀態發生改變就不能再修改狀態
        if(this.state !== 'pending')return;
        this.state = 'fulfilled';
        this.value = result;
        setTimeout( ()=>{
           this.fulfilledEvent.forEach(fulfillCb=>{
            if (typeof rejectCb === 'function') rejectCb(this.value);   
           }) 
        } )
    };
     // 處理Promise的異常
    try {
      executor(resolve, reject);
    } catch (e) {
      reject(e)
    }

  }

  then (resolveFn, rejectFn) {
    // 若是then方法中沒有傳遞resolveFn或者rejectFn,要自動補全

    if (!resolveFn) {
      resolveFn = result => result;
    }

    if (!rejectFn) {
      rejectFn = reason => {
        throw new Error(reason)
      }
    }

    return new MyPromise((resolve, reject) => {
      // 不是直接把函數放進去,由於須要判斷當前函數是否返回一個Promise實例
      this.fulfilledEvent.push((result) => {
        try {
          let x = resolveFn(result);
          x instanceof MyPromise
            ? x.then(resolve, reject)
            : resolve(result);
        } catch (e) {
          reject(e)
        }
      });

      this.rejectedEvent.push(reason => {
        try {
          let x = rejectFn(reason);
          x instanceof MyPromise
            ? x.then(resolve, reject)
            : resolve(x); // 若是不是Promise實例,直接執行下一個then中的resolve
        } catch (e) {
          reject(e);
        }
      })
    })
    }
}
複製代碼

使用

new MyPromise((resolve, reject) => {
  console.log(1);
  reject('abc');
}).then(function (res) {
  console.log(2);
}, function (err) {
  console.log(3)
}).then((res) => {
  console.log(4)
}, function () {
  console.log(5)
});
console.log(6);
複製代碼
相關文章
相關標籤/搜索