将async.waterfall转换为培根

时间:2014-07-25 06:35:16

标签: javascript bacon.js

我正在尝试将Baconjs集成到我当前的Nodejs项目中,在这个项目中我使用Async https://github.com/caolan/async来处理回调。其中一种方法是async.waterfall 现在我想使用Bacon.fromNodeCallback(...)将它移植到Bacon。 我在NodeJS中的代码:

async.waterfall([
  function findCondition(callback) {
    conditionBoundary.findById(condition.id, callback);
  },

  function updateCondition(loadedCondition, callback) {
     if(loadedCondition) {
      condition.created = loadedCondition.created;

      conditionBoundary.updateCondition(condition, function(error, numberOfDocs) {
        if(error) {
          return callback(error);
        }

        if(loadedCondition.prettyUrl && loadedCondition.prettyUrl !== condition.prettyUrl) {
          return callback(null, true, loadedCondition);
        }

        callback(null, false, null);
      });
    }
  },

  function updateLinkInConditionDescription(isUpdated, loadedCondition, callback) {
    if(isUpdated) {

      conditionBoundary.findByPrettyUrlInDescription(loadedCondition.prettyUrl, function(error, docs) {
        if(error) {
          return callback(null, false);
        }

        async.each(docs, function(doc, eachCallback) {
          var desc = doc.vietnamese.description;
          desc = desc.replace(new RegExp(loadedCondition.prettyUrl, "gmi"), condition.prettyUrl);

          conditionBoundary.updateVietnameseDescription(doc.id, desc, eachCallback);
        }, function(error) {
          callback(null, false);
        });
      });
    } else {
      return callback(null, true);
    }
  }
], function(error, result) {
  if(error) {
    return done(false, util.error("Failed to update condition")("system"));
  }

  done(true, { message: "Condition has been updated" });
});

所以我这样做了:

var result1 = Bacon.fromNodeCallback(fn, params...);
result1.onValue(function(val) {
  // perform some logic

  var result2 = Bacon.fromNodeCallback(fn2, params...);
  result2.onValue(function(val)) { .... }

  // and so on...
});

我觉得我做得不对。那么实现这一目标的正确方法是什么? 我只是想和培根一起玩,所以任何帮助都能得到真正的体会。 谢谢!

1 个答案:

答案 0 :(得分:0)

好吧,在google搜索本文http://abesto.net/bacon-js-on-the-server/之后,我终于解决了自己的问题。它让我思考我的问题以及我需要用Bacon来存档目标,而不是专注于将async.waterfall方法转换为Bacon。所以我在这里发布我的代码,希望有人发现它有用:

var oldConditionStream = Bacon.fromNodeCallback(conditionBoundary,
                                                "findById",
                                                info.id).flatMap(function(oldCondition) {
  if(oldCondition) {
    return Bacon.once(oldCondition);
  } else {
    return Bacon.once(new Bacon.Error("fail"));
  }
});

oldConditionStream.onError(function(error) {
  return done(false, { message: "Failed to update condition" });
});

var updatingStream = oldConditionStream.flatMap(function(oldCondition) {
  condition.created = util.parseDate(oldCondition.created, "YYYY-MM-DD h:mm:ss a");

  return Bacon.fromNodeCallback(conditionBoundary, "updateCondition", condition).flatMap(function(nod) {
    if(!nod) {
      return Bacon.once(new Bacon.Error("fail"));
    }

    return Bacon.once(oldCondition);
  });
});

updatingStream.onError(function(error) {
  return done(false, util.error("Failed to update condition")("system"));
});
var updatingDescriptionStream = updatingStream.flatMap(function(oldCondition) {
  if(!_.isEqual(oldCondition.prettyUrl, condition.prettyUrl)) {
    var findingStream = Bacon.fromNodeCallback(conditionBoundary,
                                                    "findByPrettyUrlInDescription",
                                                    oldCondition.prettyUrl).flatMap(Bacon.fromArray);
    var anotherStream = findingStream.flatMap(function(cond) {
      var desc = cond.vietnamese.description;
      desc = desc.replace(new RegExp(oldCondition.prettyUrl, "gmi"), condition.prettyUrl);
      return Bacon.fromNodeCallback(conditionBoundary, "updateVietnameseDescription", cond.id, desc).map(true);
    });

    anotherStream.onEnd(function() {
      return Bacon.once(true);
    });

  } else {
    return Bacon.once(true);
  }
});

updatingDescriptionStream.onValue(function(flag) {
  return done(true, { message: "Condition has been updated" });
});

振作!