• 异步流程控制库GoWithTheFlow


    异步流程控制库GoWithTheFlow

    一个尾触发方式来控制异步流程的库, 有seq(顺序执行) par(同步执行) 两种方法

    博客
    http://notes.jetienne.com/2011/07/17/gowiththeflow.js-async-flow-control-with-a-zen-touch.html

    Github
    https://github.com/lumixraku/gowiththeflow.js/blob/master/gowiththeflow.js

    使用

    顺序执行

      Flow().seq(function(next) {
        setTimeout(function(){
          console.log("first job");
          next('error', 'retValue');
        },500);
      }).seq(function(next, error, result) {
        console.log(error, result);
        console.log("second job. run *after* first job");
        next();
      });
    
    

    同步执行
    最后挂载的seq将会在所有par任务执行结束后执行
    errors results是数组 保存所有的par的结果
    执行结果顺序是挂载任务的顺序

       Flow().par(function(next){
            setTimeout(function(){
              console.log("job foo");
              next(null, "foo");
            },1000);
        }).par(function(next){
          setTimeout(function(){
            console.log("job bar");
            next(null, "bar");
          },500);
        }).par(function(next){
            setTimeout(function(){
            console.log("job zoo");
            next(null, "zoo");
            },500);
        }).seq(function(next, errors, results){
            console.log("job run *after* the completion of foo and bar");
            console.assert(errors.length == 3 && errors[0] === null && errors[1] == null)
            console.assert(results.length == 3 && results[0] === 'foo' && results[1] == 'bar')
            next();
        })
    

    实现

    var Flow = function() {
      var self, stack = [],
        //等待所有同步操作完成后开始执行异步的部分
        timerId = setTimeout(function() {
          timerId = null;
          self._next();
        }, 0);
      return self = {
        destroy: function() {
          timerId && clearTimeout(timerId);
        },
    
        //seq 和par 都只是挂载了函数(把函数保存在了stacks中)  并没有执行
        //同步执行的任务都在一个元素中
        //比如 stack = [  [f1()], [f2(), f3()], [f4()]   ]
        //表示 f1()   f2()f3()      f4()   三个顺序执行的任务   其中任务2  f2f3两个函数是并行执行
        par: function(callback, isSeq) {
          if (isSeq || !(stack[stack.length - 1] instanceof Array)) {
            stack.push([]);
          }
          stack[stack.length - 1].push(callback);
          return self; //链式调用
        },
        seq: function(callback) {
          return self.par(callback, true);
        },
    
        //调用一次_next  解决一次顺序任务
        _next: function(err, result) {
          var errors = [],
            results = [],
            callbacks = stack.shift() || [], //callbacks [function(next){....}]
            nbReturn = callbacks.length, 
            isSeq = nbReturn == 1; //表明是顺序任务  比如上面 [f1()] 这种情况
          for (var i = 0; i < callbacks.length; i++) {
            (function(fct, index) {
              //fct就是异步函数 fct接受三个参数 fct(next, err, result) 
              //而这个function(err, result) 就是next
              //next接受两个参数  next('error', 'retValue');
              fct(function(error, result) {
                errors[index] = error;
                results[index] = result;
    
                if (--nbReturn == 0) { //表明此次顺序任务执行完毕  比如上面[f2,f3] 到f3的时候
                  self._next(isSeq ? errors[0] : errors, isSeq ? results[0] : results)
                }
              }, err, result);
            })(callbacks[i], i);
          }
        }
      }
    };
    
    // export in common js
    if (typeof module !== "undefined" && ('exports' in module)) {
      module.exports = Flow;
    }
    
    // Asynchronous Module Definition - http://requirejs.org/docs/whyamd.html
    if (typeof define === 'function' && define.amd) {
      define('Flow', [], function() {
        return Flow;
      });
    }
    
    
  • 相关阅读:
    Python全栈 MySQL 数据库 (表字段增、删、改、查、函数)
    Python全栈 MySQL 数据库 (简述 、安装、基本命令)
    Python全栈工程师(异常(高级)、运算符重载)
    Python全栈工程师(多继承、函数重写)
    【洛谷P3796】(模板)AC自动机(加强版)
    【洛谷P3808】(模板)AC自动机(简单版)
    【洛谷P3919】(模板)可持久化数组(可持久化线段树/平衡树)
    【洛谷P3834】(模板)可持久化线段树 1(主席树)
    【洛谷P3369】(模板)普通平衡树
    [USACO12FEB]牛券Cow Coupons
  • 原文地址:https://www.cnblogs.com/cart55free99/p/5001671.html
Copyright © 2020-2023  润新知