0

在我的小程序中,我尝试取消缩短 URL,然后检查链接是否与我的模式匹配。如果是,我想进一步处理它。但我还需要应用以前已知的 3 个参数。

将所有 3 个参数拖到每个函数中时,我的代码感觉非常笨拙。我如何在没有承诺的情况下简化这一点?

var request = require("request");

function expandUrl(shortUrl, a,b,c, callback) {
    request( { method: "HEAD", url: shortUrl, followAllRedirects: true },
        function (error, response) {
            callback(response.request.href, a,b,c);
        });
}


function checklink(unshortenedLink, a, b, c){
    matches = unshortenedLink.match(/twitter\.com\/\w+/g);
    if(matches){
        matches.forEach(function(result){
            process_twitter_link(result, a, b, c);
        });
    }
}

function process_twitter_link(link, a, b ,c ){
    console.log(link + " " + a + " " + b + " " + c);
    // std.out: twitter.com/StackJava param_a param_b param_c
}

expandUrl("https://t.co/W0DA8WVpmO", "param_a", "param_b", "param_c", checklink);
4

4 回答 4

1

如果您将它们包装在一个对象中怎么办?

function expandUrl(shortUrl, context, callback) {
    request( { method: "HEAD", url: shortUrl, followAllRedirects: true },
        function (error, response) {
            callback(response.request.href, context);
        });
}


function checklink(unshortenedLink, context){
    matches = unshortenedLink.match(/twitter\.com\/\w+/g);
    if(matches){
        matches.forEach(function(result){
            process_twitter_link(result, context);
        });
    }
}

function process_twitter_link(link, context ){
    console.log(link + " " + context.a + " " + context.b + " " + context.c);
    // std.out: twitter.com/StackJava param_a param_b param_c
}

expandUrl("https://t.co/W0DA8WVpmO", {a: "param_a", b: "param_b", c: "param_c"}, checklink);
于 2013-11-06T15:18:10.797 回答
1

由于您的问题出在回调中并且存在异步,我建议使用 Promises:

function expandUrl(shortUrl) {
    var deferred = Deferred.create();
    request( { method: "HEAD", url: shortUrl, followAllRedirects: true },
        function (error, response) {
            deferred.resolve(response.request.href,);
        });
    return deferred.promise();
}

expandUrl(shortenedUrl).done(function (resolved_url) {
    checklink(resolved_url, "param_a", "param_b", "param_c");
});

这会从 中删除 3 个参数expandUrl,但它们仍然处于打开状态checklink


我不确定 Node.js 是否有 Promise 模块。request可能会返回一个自身的承诺。您可能可以仅链接 a.then并以这种方式仅返回已解析的 url。


没有承诺:

function expandUrl(shortUrl, callback) {
    request( { method: "HEAD", url: shortUrl, followAllRedirects: true },
        function (error, response) {
            callback(response.request.href);
        });
}

expandUrl(shortenedUrl, function (resolved_url) {
    checklink(resolved_url, "param_a", "param_b", "param_c");
});
于 2013-11-06T15:18:41.693 回答
1

您可以使用bind部分应用回调:

var request = require("request");

function expandUrl(shortUrl, callback) {
    request( { method: "HEAD", url: shortUrl, followAllRedirects: true },
        function (error, response) {
            callback(response.request.href);
        });
}


function checklink(a, b, c, unshortenedLink){
    matches = unshortenedLink.match(/twitter\.com\/\w+/g);
    if(matches){
        matches.forEach(function(result){
            process_twitter_link(result, a, b, c);
        });
    }
}

function process_twitter_link(link, a, b ,c ){
    console.log(link + " " + a + " " + b + " " + c);
    // std.out: twitter.com/StackJava param_a param_b param_c
}

var checklinkWithParams = checklink.bind(null, "param_a", "param_b", "param_c");

expandUrl("https://t.co/W0DA8WVpmO", checklinkWithParams);

注意:部分应用的参数将首先出现。

于 2013-11-06T15:22:21.633 回答
1

一种减少重复的简单方法是使用.bind()

var request = require("request");

function expandUrl(shortUrl, callback) {
    request({ method: "HEAD", url: shortUrl, followAllRedirects: true },
        function (error, response) {
            callback(response.request.href);
        });
}


function checklink(a, b, c, unshortenedLink){
    matches = unshortenedLink.match(/twitter\.com\/\w+/g);
    if(matches){
        matches.forEach(function(result){
            process_twitter_link(result, a, b, c);
        });
    }
}

function process_twitter_link(link, a, b ,c ){
    console.log(link + " " + a + " " + b + " " + c);
    // std.out: twitter.com/StackJava param_a param_b param_c
}

expandUrl("https://t.co/W0DA8WVpmO", checklink.bind(null, "param_a", "param_b", "param_c"));

但是我会说checklink()不需要访问 a、b、c,但这可能取决于您是否认为它与 process_twitter_link 紧密耦合。如果他们不是,以下是可能的:

var request = require("request");

function expandUrl(shortUrl, callback) {
    request({ method: "HEAD", url: shortUrl, followAllRedirects: true },
        function (error, response) {
            callback(response.request.href);
        });
}


function checklink(iterator){
    return function (unshortenedLink) {
        matches = unshortenedLink.match(/twitter\.com\/\w+/g);
        if(matches){
            matches.forEach(iterator);
        }
    }
}

function process_twitter_link(a, b ,c ){
    return function (link) {
        console.log(link + " " + a + " " + b + " " + c);
    };
}

expandUrl("https://t.co/W0DA8WVpmO", checklink(process_twitter_link("param_a", "param_b", "param_c")));

瞧,a,b,c 只用在一个地方!

(请注意,此代码未经测试,但理论上应该可以工作)

于 2013-11-06T15:28:25.507 回答