使用fetch API时,在AJAX调用期间显示微调器

时间:2017-05-04 20:12:05

标签: javascript ajax fetch-api

在我的项目中,我正在迁移到React,因此不加载JQuery。由于我不再使用JQuery,因此对于AJAX调用我正在使用fetch。使用JQuery,我可以挂钩AJAX调用的开始和结束,因此将光标更改为微调器非常容易。我在fetch中找不到类似的钩子。除了在每个单独的AJAX调用中更改它之外,还有其他方法吗?

很多谷歌搜索都在寻找关于...... JQuery的答案。

4 个答案:

答案 0 :(得分:6)

你去了,我认为代码几乎是不言自明的:

// Store a copy of the fetch function
var _oldFetch = fetch; 

// Create our new version of the fetch function
window.fetch = function(){

    // Create hooks
    var fetchStart = new Event( 'fetchStart', { 'view': document, 'bubbles': true, 'cancelable': false } );
    var fetchEnd = new Event( 'fetchEnd', { 'view': document, 'bubbles': true, 'cancelable': false } );

    // Pass the supplied arguments to the real fetch function
    var fetchCall = _oldFetch.apply(this, arguments);

    // Trigger the fetchStart event
    document.dispatchEvent(fetchStart);

    fetchCall.then(function(){
        // Trigger the fetchEnd event
        document.dispatchEvent(fetchEnd);
    }).catch(function(){
        // Trigger the fetchEnd event
        document.dispatchEvent(fetchEnd);
    });

    return fetchCall;
};

document.addEventListener('fetchStart', function() {
    console.log("Show spinner");
});

document.addEventListener('fetchEnd', function() {
    console.log("Hide spinner");
});

以下是一个实例:https://jsfiddle.net/4fxfcp7g/4/

答案 1 :(得分:1)

获取thenable,你可以在then()中添加spinner stop函数,在收到响应后调用。并将其包装在另一个函数中以用于标题和挂钩。

function ajax(someUrl, method) {
    var myHeaders = new Headers();

    var myInit = { 
        method: method,
        headers: myHeaders
    };
    showSpinner();

    return fetch(someUrl, myInit).then(function(response) {
        //... do some with response
        hideSpinner();

        return response;
    }).catch(function(error) {
        //... tell the user the request failed and hide the spinner
        hideSpinner();

        return error;
    });
}

ajax('example.com').then(function(response) {
    // ...
}).catch(function(error) {
    // show error
});

答案 2 :(得分:0)

fetch最初发生时您可以执行的操作,setState加载为true。然后,一旦完成提取,您可以setState加载false。然后根据当前状态显示微调器。

例如,

class SomeComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = { loading: false };
  }

  loadData(e) {
    e.preventDefault();
    this.setState({ loading: true });
    fetch(....).then( res => res.json()).then( resJson => {
      // do other stuff here.
      this.setState({ loading: false });    
    });
  }

  render() {
    return (
      <div>
         <DisplayComponent />
         <button onClick={this.loadData}>Click Me</button>
         { this.state.loading ? <Spinner /> : null }
      </div>
    );
  }
}

您可以查看react conditional rendering

答案 3 :(得分:0)

我发现使用设置手动设置“ loading”标志时遇到的主要问题 true / false是很容易错误地跳过设置为false标志的错误,您的应用程序将被挂起),另一方面,当多个ajax请求被并行调用时,我不想搞砸,甚至当您要跟踪其中的一些时,会更加困难,但是在其他情况下,您要发出静默请求。

我创建了一个名为react-promise-tracker的微库,以更自动的方式进行处理。运作方式

安装承诺跟踪器

npm install react-promise-tracker --save

实施一个简单的加载指示器组件(您可以添加所需的样式),并用 promiseTrackerHoc

进行包装
import { promiseTrackerHoc } from 'react-promise-tracker';

const InnerLoadingIndicator = props => (
   props.trackedPromiseInProgress &&
   <h1>Hey some async call in progress ! Add your styling here</h1>
);

export const LoadingIndicator = promiseTrackerHoc(InnerLoadingIndicator);

在您的应用程序根组件中实例化它:

render(
  <div>
    <App />
    <LoadingIndicator/>
  </div>,
  document.getElementById("root")
);

每当您要跟踪获取或任何基于承诺的呼叫(包括异步/等待)时,只需使用 react-promise-tracker 函数 trackPromise 包裹起来:< / p>

import { trackPromise } from 'react-promise-tracker';

export class MyComponent extends Component {
  componentWillMount() {
    trackPromise(
      userAPI.fetchUsers()
        .then((users) => {
          this.setState({
            users,
          })
        })
    );
  }

  // ...
}

更多资源: -分步教程(包括添加美观的微调器):https://www.basefactor.com/react-how-to-display-a-loading-indicator-on-fetch-calls