Web中的流产控制器及其如何改善您的应用程序
#javascript #网络开发人员 #react #fetch

大家好!今天,我要告诉您什么是AbortController,为什么您可能需要它以及如何改善应用程序的性能。

介绍

在一次小型聊天中,我进行了一项调查,事实证明,只有9%的网络开发人员在一个真实的项目中使用了它,而64%的网络开发人员根本不知道它是什么。

所以让我们开始!

AbortController接口代表一个控制器对象,允许您在需要时按照或多个Web请求进行中止。

这是一个非常简单的接口,由signal属性和abort方法组成

const controller = new AbortController();
const signal = controller.signal;
const abort = controller.abort;

我们将signal传递到呼叫方法:fetch(url, { signal })
使用abort(),可以停止此通话

例子

拿来

这个简单的代码我们的应用程序:

export default function App() {
  const [url, setUrl] = useState("users");
  const [data, setData] = useState([]);
  const [loading, setLoading] = useState(false);

  useEffect(() => {
    setLoading(true);
    fetch(`https://jsonplaceholder.typicode.com/${url}`)
      .then((res) => res.json())
      .then((res) => {
        setData(res);
        setLoading(false);
      });
  }, [url]);

  return (
    <div className="App">
      <div className="nav">
        <Link to="/users" onClick={() => setUrl("users")}>
          users
        </Link>
        <Link to="/todos" onClick={() => setUrl("todos")}>
          todos
        </Link>
        <Link to="/posts" onClick={() => setUrl("posts")}>
          posts
        </Link>
      </div>
      <div className="page">
        <Switch>
          <Route path="/users" component={() => <div>Users page</div>} />
          <Route path="/todos" component={() => <div>Todos page</div>} />
          <Route path="/posts" component={() => <div>Posts page</div>} />
        </Switch>

        {loading ? (
          "loading..."
        ) : (
          <ul>
            {data?.splice(0, 5).map((item) => (
              <li key={item.id}>{item?.name || item?.title}</li>
            ))}
          </ul>
        )}
      </div>
    </div>
  );
}

这样可以工作:

app without AbortController

您可以看到所有3个请求到达目标,并依次显示在屏幕上

我们可以想象一种情况,用户在菜单中导航的速度比请求更快地在服务器上处理,这意味着我们确实需要不必要的请求

例如:用户进入“/用户”页面,请求已经开始,下一步用户来到“/post”页面,此刻我们假设他不再需要“/用户”页面,并且可以取消此请求,并且不加载服务器

这就是abortcontroller的代码的样子,我只更改了使用效果:

  useEffect(() => {
    const controller = new AbortController();
    const signal = controller.signal;

    setLoading(true);    
    fetch(`https://jsonplaceholder.typicode.com/${url}`, { signal })
      .then((res) => res.json())
      .then((res) => {
        setData(res);
        setLoading(false);
      });

    return () => {
      controller.abort();
    };
  }, [url]);

这就是发生的事情:

app with AbortController

不必要的请求已被取消!

canceled request

这是性能的主要点!

与获取相同

const controller = new AbortController();
axios.get('/user', { signal: controller.signal })

GQL

gql几乎具有相同的方式,但是您需要使用useRef

在下面的示例中,我们离开页面时取消请求:

const controllerRef = useRef(new AbortController());

const [getUser, { data }] = useLazyQuery(USER_QUERY, {
  context: {
    fetchOptions: {
      signal: controllerRef.current.signal,
    },
  },
});

useEffect(() => {
  return () => controllerRef.current.abort();
}, []);

结论

AportController是提高性能的一种简单有效的方法,您可以在项目中尝试,祝您好运!