Javascript,Builder Pattern&回调

时间:2013-01-23 10:36:08

标签: javascript node.js

我正在尝试使用Node.js为我处理一些可编写脚本的URL重定向。它工作得很好,但脚本需要尽可能简单的格式,因为它将由其他人管理。

我想要做的是使用构建器模式,以便我可以使用以下内容:

redirectWhen.isMobileDevice().urlMatches("http://www.somewhere.com").thenGoTo("http://mobile.somewhere.com");
redirectWhen.urlMatches("http://subdomain.somewhere.com").thenGoTo("http://www.somewhere.com/somefolder/");

然后我会根据结果重定向(基本上是匹配链中所有项目的最后一个获胜)。如果您想象所有函数(isMobileDevice()& urlMatches(...)执行一些简单的字符串检查,那么一切正常。

但我需要isMobileDevice()函数来执行某项HTTP请求。这意味着拥有一个在响应完成时调用的回调函数。是否有可能做到这一点&仍然保持建设者模式完好无损?我想我可以做类似的事情:

redirectWhen.isMobileDevice(function() {
  urlMatches("...").thenGoTo("...");
});

但这会增加脚本的复杂性,而不是我想要的。管理这些脚本的人知道基本的JavaScript,但如果他们必须开始嵌套回调,我想他们会很快混淆。

我猜我正在努力实现这里不可能实现的目标,但我自己也不知道足够的JS能够证实这一点!

3 个答案:

答案 0 :(得分:1)

这是完全可能的;您的构建器在每一步返回一个中间对象,在最后一步中,您最终将这些块放在一起并调用最终函数。

function redirectWhen() {
    var building = {};  // saved state goes here

    // actually implement redirection
    function build() {
        // expects building = { source: "...", target: "...", mobile: optionalBoolean}            
        if (building.mobile) {
           checkMobile();
        } else {
           finishBuild();
        }
    }

    function checkMobile() {
        // check if actually mobile by making an HTTP request
        // in the success callback, calls finishBuild - fails otherwise
        // ..
    }

    function finishBuild() {
        // accessible only if mobile not requested, or if requested and mobile check passed
        // ..
    }

    // prepare the second step
    var urlMatches = function(url) {
        building.source = url;
        return { thenGoTo: function(target) { building.target = target; build(); } }
    }

    // return the next steps
    return { 
       isMobileDevice: function() { builder.mobile = true; return urlMatches; },
       urlMatches: urlMatches
    }
}

为了支持您的移动测试,您可以将构建分为两部分(检查和回调);但这对用户来说是不透明的,用户甚至不知道任何地方都有构建函数。

答案 1 :(得分:1)

你不应该放弃优雅的建筑模式,只是为了让它以异步方式工作。您可以创建一个链接的节点列表,每个节点在成功时调用下一个节点。

我使用Chain和多个ChainNode实施设置fiddle。一些说明:

  • 每个ChainNode都有一个execute()方法和一个nextNode,当它完成自己的处理时,需要使用next()来调用它。例如,URL模式匹配器仅在URL与模式匹配时才调用下一个节点,否则它只返回(打破执行链)。
  • 可以通过从回调调用IsMobileNode到某个异步调用(例如AJAX)来实现next()。在小提琴中,一个简单的setTimeout演示了这个概念。
  • Chain保留head,表示开始执行的位置以及附加新节点的tailchain(nextNode)方法可确保链保持完整。
  • urlMatches(urlPattern)isMobileDevice()方法只是创建一个节点并将其附加到链中。
  • thenGoTo()方法链接最终节点以启动重定向。然后,它从head
  • 开始执行链

答案 2 :(得分:0)

Dan Lee对我的问题的评论也让我遇到了Q库:https://github.com/kriskowal/q。这肯定会对我想要的东西有所帮助,虽然它并不像其他答案那么简单。