Redux Saga 中的阻塞与非阻塞

什么是 Redux Saga

Redux Saga 是一种用于管理应用程序副作用 (例如异步操作和路由) 的库,其核心是 Generator 函数 的运用。 Redux Saga 库使得异步任务变得易于读取、测试、更加可靠,也能更自然地处理复杂的并发、流控制,使得异步任务完全可以与同步流程一样简单。Redux Saga 具有以下两个优点:

  • 可以做到非阻塞异步调用,使用起来比较简单。
  • 具有非常好的扩展性,可以让我们创建想要的 API 以及结构。

在编写 Redux Saga 异步任务的时候,我们常常会碰到阻塞与非阻塞操作。那么,阻塞和非阻塞有什么区别呢?简单来说,阻塞是指在执行某一个操作时,该操作会一直等待其它操作完成,才会继续执行,而且此时程序无法做其他操作。非阻塞则相反,它在执行某个操作的同时,还可以做其他操作,不停止当前进程。

为了解释阻塞和非阻塞操作在 Redux Saga 中的应用场景,以取得 GitHub 用户信息为例,我们从 fetch API 开始分析:

import { takeLatest, delay, call } from 'redux-saga/effects';
import axios from 'axios';

// 1. fetch 使用非阻塞的方式取得用户信息
export function* getUserInfo(action) {
  const { payload: { user } } = action;
  
  try {
    // 非阻塞调用
    const response = yield call(axios.get, `https://api.github.com/users/${user}`);
    console.log(`response OK`);
    
    // 该 Saga 内其他操作都将被阻塞,同时正在进行网络请求
    yield delay(5000);
    console.log(`delayed`);
  } catch (err) {
    console.log(`response failed: ${err}`);
  }
}

上面的代码展示了非阻塞调用获取用户信息,而此次调用将会在 delay 操作时进行阻塞,这也是 Saga 中常见的代码结构。注意,此时程序仍然可以做其他操作,因为这里使用的是非阻塞的方式获取数据。

现在,再看一个最常见的采用阻塞式异步调用的例子:

// 2. fetch 使用阻塞式调用取得用户信息
export function* getUserInfo(action) {
  const { payload: { user } } = action;
  
  try {
    // 阻塞调用
    const res = yield fetch(`https://api.github.com/users/${user}`);
    const data = yield res.json();
    console.log(`response OK`);
    
    // 阻塞调用,Saga 内其他操作将一直被阻塞等待用户信息
    const response = yield call(axios.get, `https://api.github.com/users/${data.name}`);
    console.log(`response OK`);
  } catch (err) {
    console.log(`response failed: ${err}`);
  }
}

上面的代码展示了阻塞式调用获取用户信息,要注意的是,fetchres.json() 两个操作都是阻塞的,也就是说,当这两个操作在执行时,程序无法执行其他操作直到这些操作完成了。同时,这种结构也会对 Saga 内部其他操作的运行产生阻塞,直到阻塞的操作完成。

怎样选择阻塞和非阻塞?

在开发过程中,我们需要根据实际的业务需求来选择阻塞和非阻塞操作。由于阻塞式异步调用会阻塞整个应用程序,因此我们的建议是使用非阻塞异步调用,这意味着我们的代码将会更加高效,并具有比阻塞式操作更好的用户体验。

如果您决定使用阻塞式异步调用,请确保在合适的地方添加延迟操作,这样才能确保其他操作不会注重到被阻塞。

总结

Redux Saga 是一种非常高效和灵活的方法来管理应用程序中的副作用。学习使用阻塞和非阻塞操作是一个重要的步骤,以帮助您更好地管理 Saga 中的异步任务,从而使得您的应用程序的性能和用户体验都能得到保证。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65923091eb4cecbf2d712db1


纠错反馈