首页 > 解决方案 > 错误处理按顺序执行回调

问题描述

我正在尝试按顺序执行函数的以下数组(避免 callbackHell)runCallbacksInSequence(我需要实现自己的函数以了解回调如何工作并避免使用 Async.js)。我不太明白回调是如何工作的,这就是我做这个练习的原因。这是我到目前为止所拥有的。总体而言,该功能runCallbacksInSequence运行良好,但我不确定我是否以正确的方式处理错误。如果您有任何想法,请告诉我我做错了什么以及如何解决它。

    function first(cb) {
      console.log('first()');
      if (!cb) return cb(new Error('Invalid object'), null);
      cb(null, 'one');
    }
    function second(cb) {
      console.log('second()');
      if (!cb) return cb(new Error('Invalid object'), null);
      cb(null, 'two');
    }
    function third(cb) {
      console.log('third()');
      if (!cb) return cb(new Error('Invalid object'), null);
      cb(null, 'three');
    }
    function last(cb) {
      console.log('last()');
      if (!cb) return cb(new Error('Invalid object'), null);
      cb(null, 'lastCall');
    }

    let fns = [first, second, third, last];

    function runCallbacksInSequence(fns, cb) {
      const chainedFns = fns.reduceRight((acc, f) => () => f(acc), cb);
      return chainedFns();
    }

    runCallbacksInSequence(fns, function(err, results) {
      if (err) return console.log('error: ' + err.message);
      console.log('outer call results: ' + results); 
    });

标签: javascript

解决方案


解决方案

以下解决方案将处理错误和异步行为

    function first(cb) {
      setTimeout(function() {
        console.log('first()');
        cb(null, 'one');
      }, 0);
    }
    function second(cb) {
      setTimeout(function() {
        console.log('second()');
        cb(null, 'two');
      }, 100);
    }
    function third(cb) {
      setTimeout(function() {
        console.log('third()');
        cb(null, 'three');
      }, 0);
    }
    function last(cb) {
      console.log('last()');
      cb(null, 'lastCall');
      // cb(new Error('Invalid object'), null);
    }

    function runCallbacksInSequence(fns, cb) {
      fns.reduce(
        (r, f) => k => r(acc => f((e, x) => (e ? cb(e) : k([...acc, x])))),
        k => k([])
      )(r => cb(null, r));
    }

    const fns = [first, second, third, last];

    runCallbacksInSequence(fns, function(err, results) {
      if (err) return console.log('error: ' + err.message);
      console.log(...results);
    });

推荐阅读