通过Q承诺链管道数据

时间:2014-07-14 14:33:29

标签: javascript node.js promise q state-monad

我正在追逐Q承诺:

Q(initialCall).then(someOtherCallThatUsesResultsFromPreviousResults)

调用通常意味着一个promisified node.js http.get调用外部REST api。使用来自先前调用的信息构造路径。同时我也想管道上一次调用的信息。链的最终结果应该是来自两个调用合并到一个对象的数据。现在,通过附加参数 - 对象明确地传递信息。任何不需要显式传递额外参数的方法吗?

function jsonRequest(pathThatIsContructedBasedOnPreviousResults, object:any) {
  var deferer = Q.defer();
    var options = capsuleOptions;
    options.path = path;

    https.get(options, function (response) {
      response.on('data', function (d) {
        var parsedJson = JSON.parse(d);
        deferer.resolve({data: parsedJson, object: object});
      })}).on('error', function(e) {deferer.reject(e);});

    return deferer.promise;
}

示例:

function getUserDetailsByEmail(email) {
    var userByEmailRequestPath = '/api/party?email=' + email;
    return jsonRequest(userByEmailRequestPath, email);
}

UserByEmail端点不会返回电子邮件作为响应JSON的一部分,我仍然希望在返回值中包含电子邮件。

2 个答案:

答案 0 :(得分:0)

你的例子很难理解。但是根据我的理解,你希望从两个来源获得输入。您可以将您的调用包装在另一个接收外部参数的函数中。我假设你正在寻找这样的东西:

function getJsonRequestExecutor( externalObject ) {
   return function( pathThatIsContructedBasedOnPreviousResults ) {
       ...
   };
}

然后你可以把它称为:

Q(initialCall)
   .then( getJsonRequestExecutor( email ) );

答案 1 :(得分:0)

如果我理解正确,您希望getUserDetailsByEmail()返回使emailpath可用的承诺以及https响应中返回的数据。

这可以通过几种不同的方式完成;我能想到两个:

<强> 1。 “预先撰写”getUserDetailsByEmail()中的对象,使用jsonRequest()中的数据进行扩充,然后将其返回到承诺包装

function jsonRequest(obj) {
    var dfrd = Q.defer(),
    var options = _.extend({}, capsuleOptions, {
        'path': obj.path
    });
    https.get(options, function (response) {
        response.on('data', function (d) {
            obj.data = JSON.parse(d);
            dfrd.resolve(obj);
        });
    }).on('error', function(e) {
        dfrd.reject(e);
    });
    return dfrd.promise;
}

function getUserDetailsByEmail(email) {
    return jsonRequest({
        email: email,
        path: '/api/party?email=' + email
    });
}

<强> 2。在从getUserDetailsByEmail()

获取异步数据后,在jsonRequest()中“后撰写”对象
function jsonRequest(path) {
    var dfrd = Q.defer();
    var options = _.extend({}, capsuleOptions, {
        'path': obj.path
    });
    https.get(options, function (response) {
        response.on('data', function (d) {
            dfrd.resolve(JSON.parse(d));
        });
    }).on('error', function(e) {
        dfrd.reject(e);
    });
    return dfrd.promise;
}

function getUserDetailsByEmail(email) {
    var path = '/api/party?email=' + email;
    return jsonRequest(path).then(function(data) {
        return {
            email: email,
            path: path,
            data: data
        };
    });
}

在两个版本中:

  • 您会看到下划线的_.extend()用于防止capsuleOptions的污染。这与解决方案没有密切关系,只是良好的做法。
  • getUserDetailsByEmail()返回具有属性.email.path.data的js普通对象的承诺。

您选择的两个版本中的哪一个(或完全不同的版本)可能由对jsonRequest()的任何其他调用所需的行为决定。在这方面,您可能会发现版本2更“自然”。