将多个参数应用于没有promises的回调 - node-js

时间:2013-11-06 15:12:47

标签: javascript node.js callback

在我的小程序中,我尝试取消删除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 个答案:

答案 0 :(得分: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);

答案 1 :(得分: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");
});

这会从expandUrl中移除3个参数,但它们仍保留在checklink


我不确定Node.js是否有promises模块。 request可能会在自身中返回一个承诺。您可能只能链接.then并以此方式返回已解析的网址。


没有承诺:

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");
});

答案 2 :(得分: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);

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

答案 3 :(得分: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")));

Voilà,a,b,c仅在一个地方使用!

(请注意,此代码未经过测试,但理论上应该有效)