头图

Front-end ers, do you feel that it is inappropriate to use the interface request that you are familiar with for so long? ? ? You may think that there is something wrong with this, so just axios.get , fetch , the request is sent, then process the returned data, and you're done. Is it really that simple? The question is, can it really be done in a unified way for the request requirements in different scenarios? Let's talk about requests!

Talk about the scene of front-end request

Let's talk about the various scenarios of front-end requests first. The following are some high-frequency scenarios encountered when making requests.

  1. When to make a request, is it triggered as soon as you enter the page, or when you click a button, or when a certain data changes, or...?
  2. Do you want to display the request status on the page?
  3. Whether a request is to be encapsulated into a function for repeated calls, such as page-turning requests;
  4. Are data caches for interfaces that users may request frequently, such as data that will be viewed repeatedly within a few seconds?
  5. After processing some data, it is necessary to operate data across pages or modules. How to do it more conveniently? Can't all be placed in the global state;
  6. Can I still submit data safely when I am offline? For example, the editor needs to automatically save drafts frequently, and what should I do if I suddenly become offline?
  7. Other request scenarios...

These request scenarios need to be handled differently in different projects or in different locations of the same project. If we simply use the request library to initiate requests, it will lose performance and elegance.

Manage request scenarios

Because of the above problems, there is a concept called Request scene management (RSM, Request scene management). Let's talk about this concept. First, the picture above, the English picture, and the translation by yourself.

image.png

Like the Flux concept, it just proposes a set of process specifications, and then each developer can refer to it and transform it to form their own unique ideas, and then code to implement it.

My understanding is that it's more like putting a robotic arm, a paint bucket or something on the request library, arming the request library, like Iron Man.

123.png

Here, this specification proposes 4 processes, which are as follows:

request timing

Describe when a request needs to be made.

  • Initialize display data, such as just entering an interface or sub-interface;
  • Human-computer interaction triggers CS interaction, which requires changing data to re-issue requests, such as page turning, filtering, sorting, fuzzy search, etc.;
  • Pre-loading data, such as pre-loading the content of the next page in the paging, predicting that the user clicks a button to pre-fetch data;
  • To operate server-side data, it is necessary to issue a request for addition, deletion and modification, such as submitting data, deleting data, etc.;
  • Synchronize the status of the server, such as polling requests in scenarios where data changes rapidly, and re-pulling data after operating a certain data;

request behavior

Describes how to handle the request.

  • Placeholder request, displaying loading, skeleton diagram, or the last real data used when requesting;
  • Cache high-frequency responses, and execute requests multiple times will use fresh data;
  • Multi-request serial and parallel;
  • Anti-shake for frequent requests, avoid front-end data flashing, and reduce server pressure;
  • Important interface retry mechanism to reduce the probability of request failure caused by network instability;
  • Silent submission, when you only care about submitting data, directly respond to the success event after submitting the request, and the background ensures that the request is successful;
  • Submit offline, temporarily store the submitted data locally when offline, and submit it after network connection;

request event

Indicates that the request is sent with the request parameters and the response is obtained. This is the most commonly used axios , fetch , XMLHttpRequest and so on, look! Here we have to re-understand the positioning of the above request schemes, which is only one of the links in the management of request scenarios.

Response Data Management

As the name suggests, it is to manage the response data in a unified manner, and the response data can be operated at any location. This part is basically used in combination with the state mechanism of the MVVM framework such as react and vue , as if There is a dedicated management response data redux , vuex You can manipulate these stateful response data across modules without any event mechanism.

  • Remove the cached response data and pull it from the server when the request is made again;
  • Update the cached response data, which can update the response data at any location, which is very beneficial to update data across pages;
  • Refreshing the response data can re-refresh the response data at any location, and it is also very beneficial to update data across pages;
  • Custom setting cache, when requesting batch data, you can manually set the cache for batch data one by one, so as to satisfy the cache hit of subsequent single data;

alova, an RSM implementation library

alova is a relatively easy-to-use RSM implementation library I found, because its design is really similar to axios , novices can get started quickly, and it can also work with any request Libraries to collaborate.

In a simple demonstration of the usage of alova , we will finally start to practice the code. Before using alova , we need to create an instance, assuming we use it in the vue project.

 import { createAlova } from 'alova';
import VueHook from 'alova/vue';
import GlobalFetch from 'alova';

const alovaInstance = createAlova({
    // 请求接口前缀
    baseURL: 'https://api.alovajs.org',
    
    // 用于给mvvm库创建状态化响应数据
    // vue项目传入VueHook,react项目传入ReactHook
    statesHook: VueHook,
    
    // 传一个请求适配器,GlobalFetch是我们提供的fetch api适配器
    // 你想用axios也可以自定义一个适配器
    requestAdapter: GlobalFetch(),
    
    // 是不是有熟悉的味道
    beforeRequest(config) {
        config.headers.token = 'tokenxxx';
    },
    async responsed(response) {
      const json = await response.json();
      if (json.code !== 200) {
        throw new Error(json.message);
      }
      return json.data;
    },
});

Take Todo as an example, initiate a todo details request

 // 先定义一个请求函数,该函数返回的是一个请求对象,表示一次请求的信息,但还不会实际发出请求
// 它的用法很接近axios
const getTodoDetail = id => alovaInstance.Get('/todo', {
    params: {
        id
    },
    
    // 本地缓存50000毫秒,再次请求时将会命中缓存,而不会再次发起请求
    localCache: 50000,
});

// 发起请求
const {
    // loading是加载状态值,当加载时它的值为true,结束后自动更新为false
    // Vue3环境下,它是一个Ref类型的值,你可以通过loading.value访问它,或直接绑定到界面中
    loading,
    

    // 状态化的响应数据
    data: todoDetail,

    // 请求错误对象,请求错误时有值,否则为undefined
    error,

    // 成功回调绑定
    onSuccess,

    // 失败回调绑定
    onError,

    // 完成回调绑定
    onComplete,
    
} = useRequest(getTodoDetail(this.$params.todoId)); // 将请求对象传入即可发送请求
onSuccess(todoListRaw => {
  console.log('请求成功,这里也可以访问响应数据:', todoListRaw);
});
onError(error => {
  console.log('请求失败,错误信息为:', error);
});
onComplete(() => {
  console.log('请求完成,不管成功失败都会调用');
});

You can directly use the returned state of useRequest to bind to the interface

 <div v-if="loading">Loading...</div>
<div v-else-if="error" class="error">{{ error.message }}</div>
<template v-else>
    <div class="todo-title">{{ todoDetail.title }}</div>
    <div class="todo-time">{{ todoDetail.time }}</div>
</template>

submit data

 // 创建提交数据的请求对象
const createTodo = newTodo => alovaInstance.Post('/create-todo', newTodo);

const {
    loading,
    data,
    error,

    // 手动发送器请求的函数,调用后发送请求
    send: addTodo,
} = useRequest(newTodo => createTodoPoster(newTodo), {
    // 当immediate为false时,默认不发出
    immediate: false
});

// 假设这是我们需要提交的数据
const newTodo = {
    title: '新的todo项',
    time: new Date().toLocaleString()
};

// 用于提交成功后刷新todo列表数据
const { fetch } = useFetcher(alovaInstance);

// 手动发送请求
const handleAddTodo = async () => {
    try {
        cosnt result = await addTodo(newTodo);
        console.log('新增todo项成功,响应数据为:', result);
        
        // 提交成功后可能需要刷新todo列表数据,可以在这里调用fetch函数
        fetch(getTodoList());
    } catch(error) {
        console.log('新增todo项失败,错误信息为:', error);
    }
};

Click the button in the interface to initiate the request

 <!-- 忽略其他... -->
<button @click="handleAddTodo">创建todo</button>

Summarize

Because of the space, today's sharing will come here first. Here, it only demonstrates a little bit of alova's functions. Its power is more than that. It also gives us a lot of practical request processing solutions, whether it is in the project. It is very helpful to improve performance, improve code superiority, or reduce server pressure. Interested partners can go to github to learn more about it!

Guys, do you think there are any other examples of request scenarios?


爱编程的小金
39 声望7 粉丝

爱研究各种技术的小金