【问题标题】:Node.js promise with q not working as expectedNode.js 承诺与 q 没有按预期工作
【发布时间】:2014-11-04 18:30:07
【问题描述】:

这是我的方法:

var q = require('q');
var request = require("request");

exports.route = function (req, res) {
    var userId = req.query.userId;

    if (!userId) {
        res.send(JSON.stringify({
            errorCode: 400,
            error: "userId is missing, please form your query like <url>/avatar?userId=00.42.1"
        }), 400);
        return;
    }
    getAvatar(userId).then(function (success) {
            console.log('success');
            res.json(success);
        }, function (error) {
            console.log('error');
            res.json({error: error});
        }
    );


};

function getAvatar(userId) {
    var isErrorInResponse = function (error, response) {
        return typeof error !== 'undefined' || error == null || response.statusCode > 202;
    };

    var deferred = q.defer();
    var url = "http://localhost/avatar" + userId;
    console.log(url);
    request(url, function (error, response, body) {
        if (isErrorInResponse(error, response)) {
            deferred.reject(new Error({error: error, response: response, body: body}));
        } else {
            deferred.resolve(body);
        }
    });
    return deferred.promise;
};

GET localhost:8090/avatar?userId=42 produces 以下日志:

http://localhost/avatar/42
error

并将此响应发送给客户端:

{
  "error": {}
}

这是我的版本,我无法更新:

 "dependencies": {
    "consolidate": "0.9.0",
    "express": "3.1.0",
    "multipart-parser": "0.0.2",
    "mustache": "0.7.2",
    "poplib": "0.1.5",
    "q": "0.9.3",
    "q-io": "1.6.x",
    "request": "2.27.0",
    "string": "^2.2.0",
    "xml2js": "0.2.8"
  }

问题是,为什么我在deferred.reject(... 发送的承诺没有收到完整的错误,我需要进行哪些更改才能使其正常工作?

【问题讨论】:

    标签: javascript node.js promise q


    【解决方案1】:
    deferred.reject(new Error({error: error, response: response, body: body}));
    

    Error 构造函数接受一个字符串参数,而不是一个对象。传入除字符串以外的任何内容都会导致参数被转换为字符串,对于普通对象,字符串为[object Object]。因为错误对象没有任何可枚举的属性,所以JSON.stringifying 它会导致{}。您需要将字符串传递给Error 构造函数并访问消息属性。

    拒绝:

    deferred.reject(new Error(error));
    

    回复:

    getAvatar(userId).then(function (success) {
                console.log('success');
                res.json(success);
            }, function (error) {
                console.log('error');
                res.json({error: error.message});
            }
       );
    

    如果您希望错误消息成为一个对象,则必须对其进行字符串化。或者,您可以将这些属性显式添加到错误对象,当错误为JSON.stringified 时它们会显示出来,但这也会显示stack 属性,因为Q 添加它以支持长堆栈跟踪.

    【讨论】:

    • 感谢您的解决方案,现在我将 json 字符串化并再次解析它。基于此,我再次检查了 api 文档并找到了定义:'Q.reject(reason) Returns a promise that is denied with reason.' (github.com/kriskowal/q/wiki/API-Reference)
    • 你应该回复状态 500 res.json(500, {error: error.message});
    猜你喜欢
    • 2018-09-19
    • 1970-01-01
    • 2019-12-03
    • 1970-01-01
    • 2013-06-05
    • 1970-01-01
    • 1970-01-01
    • 2012-04-19
    • 2017-01-16
    相关资源
    最近更新 更多