zoukankan      html  css  js  c++  java
  • [web] 使用Promise封装fetch实现网络超时,终止请求的功能

    转载自:https://www.jianshu.com/p/d66421c826ae

    本文参考了Fetch进阶指南

    缘起

    fetch网络请求没有timeout机制,也没有about机制。
    而日常开发过程中,必定要对请求超时做处理,也要及时终止不需要的网络请求。
    所以,就需要自己封装fetch来实现。

    实现

    Promise.race(promise1,promise2,...) 方法返回一个Promise对象, 只要参数中任意一个Promise 被 resolve 或者 reject 后, 外部的Promise 就会以相同的值被 resolve 或者 reject.

    import React, {Component} from 'react';
    
    /**
     * 使用Promise封装Fetch,具有网络超时、请求终止的功能
     */
    class NetUtil extends Component {
    
        static baseUrl = "http://xxxx:81/api/";
        static token = '';
    
        /**
         * post请求
         * url : 请求地址
         * data : 参数(Json对象)
         * callback : 回调函数
         * */
        static fetch_request(url, method, params = '') {
            let header = {
                'Accept': 'application/json',
                'Content-Type': 'application/json;charset=UTF-8',
                'accesstoken': NetUtil.token,
            }
            let promise = null;
            if (params == '') {
                promise = new Promise((resolve, reject) => {
                    fetch(NetUtil.baseUrl + url, {method: method, headers: header})
                        .then(response => response.json())
                        .then(responseData => resolve(responseData))
                        .then(err => reject(err))
                })
            } else {
                promise = new Promise((resolve, reject) => {
                    fetch(NetUtil.baseUrl + url, {method: method, headers: header, body: JSON.stringify(params)})
                        .then(response => response.json())
                        .then(responseData => resolve(responseData))
                        .then(err => reject(err))
                })
            }
            return NetUtil.warp_fetch(promise);
        }
    
        /**
         * 创建两个promise对象,一个负责网络请求,另一个负责计时,如果超过指定时间,就会先回调计时的promise,代表网络超时。
         * @param {Promise} fetch_promise    fetch请求返回的Promise
         * @param {number} [timeout=10000]   单位:毫秒,这里设置默认超时时间为10秒
         * @return 返回Promise
         */
        static warp_fetch(fetch_promise, timeout = 10000) {
            let timeout_fn = null;
            let abort = null;
            //创建一个超时promise
            let timeout_promise = new Promise(function (resolve, reject) {
                timeout_fn = function () {
                    reject('网络请求超时');
                };
            });
            //创建一个终止promise
            let abort_promise = new Promise(function (resolve, reject) {
                abort = function () {
                    reject('请求终止');
                };
            });
            //竞赛
            let abortable_promise = Promise.race([
                fetch_promise,
                timeout_promise,
                abort_promise,
            ]);
            //计时
            setTimeout(timeout_fn, timeout);
            //终止
            abortable_promise.abort = abort;
            return abortable_promise;
        }
    }
    
    export default NetUtil;
  • 相关阅读:
    密码
    日历游戏
    最大公约数
    从map到hash
    9、RabbitMQ-集成Spring
    8、RabbitMQ-消息的确认机制(生产者)
    7、RabbitMQ-主题模式
    6、RabbitMQ-路由模式
    5、RabbitMQ-订阅模式 Publish/Subscribe
    4、RabbitMQ-消息应答与消息持久化
  • 原文地址:https://www.cnblogs.com/0616--ataozhijia/p/12600128.html
Copyright © 2011-2022 走看看