• 关于fetch


    前言:

      fetch是用来取代传统的XMLHttpRequest的。 它的优点很多,包括链式调用的语法、返回promise等。

    什么是fetch?

      fetch api是基于promise的设计,它是为了取代传统xhr的不合理的写法而生的。

    WHY fetch?

      xhr请求写起来非常的混乱,如下所示:

    var xhr = new XMLHttpRequest();
    xhr.open('GET', url);
    xhr.responseType = 'json';
    
    xhr.onload = function() {
      console.log(xhr.response);
    };
    
    xhr.onerror = function() {
      console.log("Oops, error");
    };
    
    xhr.send();

      

      但是使用fetch之后,如下所示:

     
    fetch(url).then(function(response) {
      return response.json();
    }).then(function(data) {
      console.log(data);
    }).catch(function(e) {
      console.log("Oops, error");
    });
     

      这种链式调用的风格看上去会非常舒服。

      如果我们再使用了箭头函数就会更加简洁了。 

    fetch(url).then(response => response.json())
      .then(data => console.log(data))
      .catch(e => console.log("Oops, error", e))

      

      通过使用fetch api,可以将传统的xhr的粗糙的使用方法转化的如此精简,实在是好! 

      但是呢? 使用Promise,还是可以很明显看到callback的使用,不急,我们还可以使用 async、await :

     
    // Async/Await requirements: Latest Chrome/FF browser or Babel: https://babeljs.io/docs/plugins/transform-async-to-generator/
    // Fetch requirements: Latest Chrome/FF browser or Github fetch polyfill: https://github.com/github/fetch
    
    // async function
    async function fetchAsync () {
      // await response of fetch call
      let response = await fetch('https://api.github.com');
      // only proceed once promise is resolved
      let data = await response.json();
      // only proceed once second promise is resolved
      return data;
    }
    
    // trigger async function
    // log response or catch error of fetch promise
    fetchAsync()
        .then(data => console.log(data))
        .catch(reason => console.log(reason.message))
     

      这样看上去是不是就好多了呢?

    注意: 对于async和await的使用还是很明确的,就是一般我们在一个异步函数之前添加 await 关键词,然后在这个 await 的相关代码外面使用的时 async 函数,这样的结合才是合适的。

    利用 async 和 await,我们就可以像写同步代码一样来写异步代码啦! 

    但是呢,目前async 和 await 的支持性还不是很好,目前还无法在一般的浏览器中使用!

       

      

    基本使用方法:

    fetch必须接受一个资源路径作为参数,并且返回了一个promise,所以我们可以直接使用链式调用的方式。 

     
     fetch("/getAllProduct").then(function(res) {
                return res.json();
            }).then(function (data) {
                if (data.code == 200) {
                  console.log('获取到所有产品' ,data.data);
                  that.props.addAllProduct(data.data);
                } else {
                  console.log(data.message);
                }
            })
     

    这样,我们就可以发送一个ajax请求。

     
    /* 对客户端的返回数据封装
     * @param [code] (number) code为返回的状态码
     * @param [message] (string) message为返回的信息
     * @param [data] (any) data是可选的,为返回给前端的数据
     */
    // 注意: retrunJson中的res为node处理接口的回调函数中的res,这个是必须的。
    function returnJson(res, code, message, data) {
        var response = {
            code: code,
            message: message
        };
        if (typeof data !== 'undefined') {
            response.data = data;
        }
        res.json(response);
       // 返回这个请求之后,必须要 res.end()表示请求的结束,否则后台可能会崩溃。 res.end(); } router.post('/register', function (req, res) { let userName = req.body.username, password = req.body.password, passwordAgain = req.body.passwordAgain, type = req.body.type; console.log(userName, password, type); if (type == 1) { if (password == passwordAgain) { let managerId = uuidv1(); console.log(userName, password, passwordAgain); var newUser = new Manager({ name: userName, password: password, type: req.body.type, managerId: managerId }); Manager.find(userName, function (err, user) { if (err) { returnJson(res, 5001, '服务器错误,注册失败'); } else { if (user !== null) { returnJson(res, 4003, "此用户已经注册!"); } else { // 如果符合条件,就注册该用户,将数据保存在数据库。 newUser.save(function (err, user) { if (err) { // 服务器端错误,失败返回状态码500 returnJson(res, 500, "用户注册失败!"); } else { // user数据较简单,直接传递user即可,如果复杂,我们可以考虑使用对象形式传递更多数据。 returnJson(res, 200, "用户注册成功!", user); } }); } } }); } else { returnJson(res, 4001, "用户两次输入密码不一致!"); } } else if( type == 2) { if (password == passwordAgain) { let userId = uuidv1(); console.log(userName, password, passwordAgain); var newUser = new User({ name: userName, password: password, type: req.body.type, userId: userId }); User.find(userName, function (err, user) { if (err) { returnJson(res, 5001, '服务器错误,注册失败'); } else { if (user !== null) { returnJson(res, 4003, "此用户已经注册!"); } else { // 如果符合条件,就注册该用户,将数据保存在数据库。 newUser.save(function (err, user) { if (err) { // 服务器端错误,失败返回状态码500 returnJson(res, 500, "用户注册失败!"); } else { // user数据较简单,直接传递user即可,如果复杂,我们可以考虑使用对象形式传递更多数据。 returnJson(res, 200, "用户注册成功!", user); } }); } } }); } else { returnJson(res, 4001, "用户两次输入密码不一致!"); } } });
     

    这样,我们就可以处理一个ajax请求。

    注意点:

    1、fetch() 返回的是一个Promise对象。

      fetch使用的promise对象可以使得我们使用同步的方式写异步函数。

    2、 fetch api是可以结合 async 和 await 来使用的。 

      fetch是基于promise实现的,但是使用promise的写法,我们还是可以看到callback的影子,如果结合 async和await来使用,还是非常不错的。

    3、 Fetch api 提供的spi囊括但是不限于xhr的所有功能。

    4、 fetch api 可以跨域。 

      参考: https://fetch.spec.whatwg.org/#http-cors-protocol

      跨域请求必须包括  Origin 作为header. 

         以上。

        我们在发送fetch请求的时候就会使用到CORS协议,尽管这些对于开发者来说是透明的,但是浏览器还是会发送 origin 字段。 

    5、fetch提供了对request和response对象的通用定义。

      Fetch 提供了对 Request 和 Response (以及其他与网络请求有关的)对象的通用定义。所以在一个Fetch请求中,完全可以只使用Request 和 Response两个对象,通过Request 设置参数,通过Response 对返回值进行处理。 

     所以,我们可以将一个fetch定义如下:

    var myHeaders = new Headers();
    myHeaders.append('Content-Type', 'image/jpeg');
    var option = { method: 'GET',
        headers: myHeaders,
        mode: 'cors',
        cache: 'default' };
    var myRequest = new Request('https://api.github.com/users/mzabriskie',option);
    fetch(myRequest).then(function(response) {
        ... 
    });

    本文转自:https://www.cnblogs.com/zhuzhenwei918/p/7249691.html

  • 相关阅读:
    c#抓取和分析网页的类
    优化 Microsoft Windows Media Services 9 Series
    IIS中HTTP压缩概述
    网站CND加速器是什么
    如何分析网页数据并且去除Html标签(C#)
    告别ASP.NET操作EXCEL的烦恼(总结篇)
    Windows Media Services 9 系列常见问题解答
    字体收藏
    水晶按钮最终效果图
    gzip
  • 原文地址:https://www.cnblogs.com/czy960731/p/10882498.html
Copyright © 2020-2023  润新知