我正在尝试使用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能够证实这一点!
答案 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
,表示开始执行的位置以及附加新节点的tail
。 chain(nextNode)
方法可确保链保持完整。urlMatches(urlPattern)
和isMobileDevice()
方法只是创建一个节点并将其附加到链中。thenGoTo()
方法链接最终节点以启动重定向。然后,它从head
。答案 2 :(得分:0)
Dan Lee对我的问题的评论也让我遇到了Q库:https://github.com/kriskowal/q。这肯定会对我想要的东西有所帮助,虽然它并不像其他答案那么简单。