异步控制流程 控制流篇-timeout、waterfall瀑布流

文章目录

  • 控制流
    • timeout
    • waterfall

控制流

timeout

  • 当异步任务没在指定时间内触发callback时,触发报错

基本使用

function myFunction(params, callback) {
    console.log('1',params)
    callback(null, '123')
}

var wrapped = nac.timeout(myFunction, 1000);

wrapped({ bar: 'bar' }, function(err, data) {
   console.log(data)
});

实现

function timeout(func, millisec, info) {
  var callback, timer;
  return wrappedFunc;

  function wrappedFunc() {
    timer = setTimeout(timeoutCallback, millisec);
    var args = createArray(arguments);
    var lastIndex = args.length - 1;
    callback = args[lastIndex];
    args[lastIndex] = injectedCallback;
    simpleApply(func, args); // 将 warpped 参数传递给 func,修改回调为 injectedCallback 清除定时器并触发 callback
  }

  function timeoutCallback() {
    var name = func.name || 'anonymous';
    var err = new Error('Callback function "' + name + '" timed out.');
    err.code = 'ETIMEDOUT';
    if (info) {
      err.info = info;
    }
    timer = null;
    callback(err); // 触发 callback 传递error
  }

  function injectedCallback() {
    if (timer !== null) {
      simpleApply(callback, createArray(arguments));  // 触发 callback
      clearTimeout(timer);
    }
  }

  function simpleApply(func, args) {
    switch (args.length) {
      case 0:
        func();
        break;
      case 1:
        func(args[0]);
        break;
      case 2:
        func(args[0], args[1]);
        break;
      default:
        func.apply(null, args);
        break;
    }
  }
}

waterfall

  • 在调用done的时候,收集参数并改变索引传递触发下一个函数
function waterfallIterator(func, args, next) {
  switch (args.length) {
    case 0:
    case 1:
      return func(next);
    case 2:
      return func(args[1], next);
    case 3:
      return func(args[1], args[2], next);
    case 4:
      return func(args[1], args[2], args[3], next);
    case 5:
      return func(args[1], args[2], args[3], args[4], next);
    case 6:
      return func(args[1], args[2], args[3], args[4], args[5], next);
    default:
      args = slice(args, 1);
      args.push(next);
      return func.apply(null, args);
  }
}

function waterfall(tasks, callback) {
  callback = callback || noop;
  if (!checkWaterfallTasks(tasks, callback)) {
    return;
  }
  var func, args, done, sync;
  var completed = 0;
  var size = tasks.length;
  waterfallIterator(tasks[0], [], createCallback(0));

  function iterate() {
    waterfallIterator(func, args, createCallback(func));
  }

  function createCallback(index) {
    return function next(err, res) {
      if (index === undefined) {
        callback = noop;
        throwError();
      }
      index = undefined;
      if (err) {
        done = callback;
        callback = throwError;
        done(err);
        return;
      }
      if (++completed === size) {
        done = callback;
        callback = throwError;
        if (arguments.length <= 2) {
          done(err, res);
        } else {
          done.apply(null, createArray(arguments));
        }
        return;
      }
      if (sync) {
        args = arguments;
        func = tasks[completed] || throwError;
        nextTick(iterate);
      } else {
        sync = true;
        waterfallIterator(tasks[completed] || throwError, arguments, createCallback(completed));
      }
      sync = false;
    };
  }
}

你可能感兴趣的:(设计模式&代码优化,javascript,前端,html)