search
HomeWeb Front-endJS TutorialInterpretation of redux-saga principle (code example)

Interpretation of redux-saga principle (code example)

Oct 29, 2018 pm 02:34 PM
javascriptreact.jsredux

The content of this article is about the interpretation of redux-saga principle (code example). It has certain reference value. Friends in need can refer to it. I hope it will be helpful to you.

The author has recently been working on some backend projects, using Ant Design Pro, which uses redux-saga to process asynchronous data flows. This article will give a simple interpretation of the principle of redux-saga and will implement a A simple version of redux-saga.

Automatic process control of Generator function

In redux-saga, saga refers to some long-term operations, represented by the generator function. The power of the generator function is that it can manually pause and resume execution, and can interact with data outside the function body. See the following example:

function *gen() {
  const a = yield 'hello';
  console.log(a);
}
cont g = gen();
g.next(); // { value: 'hello', done: false }
setTimeout(() => g.next('hi'), 1000)  // 此时 a => 'hi'   一秒后打印‘hi'

It can be seen that when the generator function performs the next operation completely depends on The external scheduling timing, and its internal execution status are also determined by external input, which makes the generator function convenient for asynchronous process control. For example, we first read the content of a file as a query parameter, then request a query interface and print out the returned content:

function getParams(file) {
  return new Promise(resolve => {
    fs.readFile(file, (err, data) => {
      resolve(data)
    })
  })
}
function getContent(params) {
  //  request返回promise
  return request(params)
}
function *gen() {
  const params = yield getParams('config.json');
  const content = yield getContent(params);
  console.log(content);
}

We can manually control the execution of the gen function:

const g = gen();
g.next().value.then(params => {
  g.next(params).value.then(content => {
    g.next(content);
  })
})

The above can achieve our purpose, but it is too cumbersome. What we want is that the generator function can be automatically executed. We can write a simple automatic execution function as follows:

function genRun(gen) {
  const g = gen();
  next();
  function next(err, pre) {
    let temp;
    (err === null) && (temp = g.next(pre));
    (err !== null) && (temp = g.throw(pre));

    if(!temp.done) {
      nextWithYieldType(temp.value, next);
    }
  }
}
function nextWithYieldType(value, next) {
  if(isPromise(value)) {
    value
      .then(success => next(null, success))
      .catch(error => next(error))
  } 
}
genRun(gen);

At this time, the generator function can be automatically executed. In fact, we can find that the internal state of the generator is completely determined by nextWithYieldType. We can execute different processing logic according to the type of yield.

Effect

In fact, sagaMiddleware.run(saga) can be regarded as similar to genRun(saga), and saga is composed of effects, then the effect is What? Explanation of redux-saga official website: one The effect is a Plain Object JavaScript object containing some elements that will be used by the saga middleware instructions to execute. redux-saga provides many Effect creators, such as call, put, take, etc. Take call as an example:

function saga*() {
  const result = yield call(genPromise);
  console.log(result);
}

call(genPromise) generates an effect, which may be similar to the following :

{
  isEffect: true,
  type: 'CALL',
  fn: genPromise
}

In fact, the effect only indicates the intention, and the actual behavior is completed by nextWithYieldType similar to the above, for example:

function nextWithYieldType(value, next) {
  ...
  if(isCallEffect(value)) {
    value.fn(). then(success => next(null, success)).catch(error => next(error))  
  } 
}

When the promise returned by the genPromise function is resolved, it will be printed. The results.

Producers and consumers

Observe the following example

function *saga() {
  yield take('TEST');
  console.log('test...');
}

sagaMiddleware.run(test);

saga will block at take('TEST'), only dispatch is executed ({type: 'TEST'}) before saga can continue to run (note: the dispatch method at this time is packaged by sagaMiddleware). This feels very much like take is a producer, waiting for disaptch consumption. In fact, take is just an Effect generator, and the specific processing logic is still completed in nextWithYieldType, similar to:

function nextWithYieldType(value, next) {
  ...
  // take('TEST')生成的effect简单的认为是  {isEffect: true, type: 'TAKE', name: 'TEST'}
  if(isTakeEffect(value)) {
    channel.take({pattern: value.name, cb: params => next(null, params)})  
  } 
}

channel is a task generator. It has two methods: take to generate tasks and put to consume tasks:

function channel() {
  /*
    task = {
      pattern,
      cb
    }
  */
  let _task = null;

  function take(task) {
    _task = task;
  }

  function put(pattern, args) {
    if(!_task) return;
    if(pattern == _task.pattern) _task.cb.call(null, args);
  }

  return {
    take,
    put
  }
}

Obviously the task is consumed when dispatch is executed. This work is done in sagaMiddleware , similar to the following:

const sagaMiddleware = store => {
  return next => action => {
    next(action);
    
    const { type, ...payload } = action;
    channel.put(type, payload);
  }
}

Seeing here we can find that what we need to do is to continuously improve the nextWithYieldType function. After completing the logic corresponding to put, fork, and takeEvery, a redux with basic functions -saga was born, so I won’t go into details about the implementation of these functions.

The above is the detailed content of Interpretation of redux-saga principle (code example). For more information, please follow other related articles on the PHP Chinese website!

Statement
This article is reproduced at:segmentfault. If there is any infringement, please contact admin@php.cn delete
JavaScript Engines: Comparing ImplementationsJavaScript Engines: Comparing ImplementationsApr 13, 2025 am 12:05 AM

Different JavaScript engines have different effects when parsing and executing JavaScript code, because the implementation principles and optimization strategies of each engine differ. 1. Lexical analysis: convert source code into lexical unit. 2. Grammar analysis: Generate an abstract syntax tree. 3. Optimization and compilation: Generate machine code through the JIT compiler. 4. Execute: Run the machine code. V8 engine optimizes through instant compilation and hidden class, SpiderMonkey uses a type inference system, resulting in different performance performance on the same code.

Beyond the Browser: JavaScript in the Real WorldBeyond the Browser: JavaScript in the Real WorldApr 12, 2025 am 12:06 AM

JavaScript's applications in the real world include server-side programming, mobile application development and Internet of Things control: 1. Server-side programming is realized through Node.js, suitable for high concurrent request processing. 2. Mobile application development is carried out through ReactNative and supports cross-platform deployment. 3. Used for IoT device control through Johnny-Five library, suitable for hardware interaction.

Building a Multi-Tenant SaaS Application with Next.js (Backend Integration)Building a Multi-Tenant SaaS Application with Next.js (Backend Integration)Apr 11, 2025 am 08:23 AM

I built a functional multi-tenant SaaS application (an EdTech app) with your everyday tech tool and you can do the same. First, what’s a multi-tenant SaaS application? Multi-tenant SaaS applications let you serve multiple customers from a sing

How to Build a Multi-Tenant SaaS Application with Next.js (Frontend Integration)How to Build a Multi-Tenant SaaS Application with Next.js (Frontend Integration)Apr 11, 2025 am 08:22 AM

This article demonstrates frontend integration with a backend secured by Permit, building a functional EdTech SaaS application using Next.js. The frontend fetches user permissions to control UI visibility and ensures API requests adhere to role-base

JavaScript: Exploring the Versatility of a Web LanguageJavaScript: Exploring the Versatility of a Web LanguageApr 11, 2025 am 12:01 AM

JavaScript is the core language of modern web development and is widely used for its diversity and flexibility. 1) Front-end development: build dynamic web pages and single-page applications through DOM operations and modern frameworks (such as React, Vue.js, Angular). 2) Server-side development: Node.js uses a non-blocking I/O model to handle high concurrency and real-time applications. 3) Mobile and desktop application development: cross-platform development is realized through ReactNative and Electron to improve development efficiency.

The Evolution of JavaScript: Current Trends and Future ProspectsThe Evolution of JavaScript: Current Trends and Future ProspectsApr 10, 2025 am 09:33 AM

The latest trends in JavaScript include the rise of TypeScript, the popularity of modern frameworks and libraries, and the application of WebAssembly. Future prospects cover more powerful type systems, the development of server-side JavaScript, the expansion of artificial intelligence and machine learning, and the potential of IoT and edge computing.

Demystifying JavaScript: What It Does and Why It MattersDemystifying JavaScript: What It Does and Why It MattersApr 09, 2025 am 12:07 AM

JavaScript is the cornerstone of modern web development, and its main functions include event-driven programming, dynamic content generation and asynchronous programming. 1) Event-driven programming allows web pages to change dynamically according to user operations. 2) Dynamic content generation allows page content to be adjusted according to conditions. 3) Asynchronous programming ensures that the user interface is not blocked. JavaScript is widely used in web interaction, single-page application and server-side development, greatly improving the flexibility of user experience and cross-platform development.

Is Python or JavaScript better?Is Python or JavaScript better?Apr 06, 2025 am 12:14 AM

Python is more suitable for data science and machine learning, while JavaScript is more suitable for front-end and full-stack development. 1. Python is known for its concise syntax and rich library ecosystem, and is suitable for data analysis and web development. 2. JavaScript is the core of front-end development. Node.js supports server-side programming and is suitable for full-stack development.

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
3 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Best Graphic Settings
3 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. How to Fix Audio if You Can't Hear Anyone
3 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: How To Unlock Everything In MyRise
4 weeks agoBy尊渡假赌尊渡假赌尊渡假赌

Hot Tools

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

This project is in the process of being migrated to osdn.net/projects/mingw, you can continue to follow us there. MinGW: A native Windows port of the GNU Compiler Collection (GCC), freely distributable import libraries and header files for building native Windows applications; includes extensions to the MSVC runtime to support C99 functionality. All MinGW software can run on 64-bit Windows platforms.

MantisBT

MantisBT

Mantis is an easy-to-deploy web-based defect tracking tool designed to aid in product defect tracking. It requires PHP, MySQL and a web server. Check out our demo and hosting services.

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use