【问题标题】:nodejs promise better way to handle errors happening in promise implementation?nodejs 承诺更好的方法来处理承诺实现中发生的错误?
【发布时间】:2018-10-22 23:47:18
【问题描述】:

这可能被问了很多次,但我找不到适合我的解决方案的示例。这是我返回承诺并模拟响应主体使其失败的主要示例。我正在尝试处理异常以捕获它并正确记录它。

const request = require('request');

var url = "https://bittrex.com/Api/v2.0/pub/market/GetTicks?marketName=BTC-STRAT&tickInterval=hour";

function requestMarketData() {
    return new Promise(function(resolve, reject) {
        request(url, function(err, res, body) {
            if (err) {
                console.log(err);
                return reject(err);
            }
            console.log("GET: " + url);
            var result = JSON.parse("<HTML>"); // make JSON.parse fail
            return resolve(result);
        });
    });
}

async function getMarketData() {
    var result = await requestMarketData();
}

getMarketData();

我尝试处理它的第一种方法;

async function getMarketData() {
    try {
        var result = await requestMarketData();
    } catch(err) {
        console.log("Failed result: " + err);
    }
}

由于异步工作而无法正常工作。

第二种方式,为返回的 promise 添加 catch 处理程序;

function requestMarketData() {
    return new Promise(function(resolve, reject) {
        request(url, function(err, res, body) {
            if (err) {
                console.log(err);
                return reject(err);
            }
            console.log("GET: " + url);
            var result = JSON.parse("<HTML>"); // make JSON.parse fail
            return resolve(result);
        });
    }).catch(err => {
        console.log("Failed result: " + err);
    });
}

效果不佳。

第三条路;

function requestMarketData() {
    return new Promise(function(resolve, reject) {
        request(url, function(err, res, body) {
            if (err) {
                console.log(err);
                return reject(err);
            }
            console.log("GET: " + url);
            var result = [];
            try {
                result = JSON.parse("<HTML>"); // make JSON.parse fail
            } catch(err) {
                result = [{foo: "bar"}];
                return reject(result);
            }
            return resolve(result);
        });
    });
}

终于奏效了。但是,我的问题是在 Promise 实现之外有更好的方法来处理这些错误吗?

非常感谢!

【问题讨论】:

  • “由于异步工作而无法正常工作。” 这不是预期的原因。 await一个被拒绝的promise应该抛出一个错误,你可以用try捕获。问题是解析失败不会导致 promise 被拒绝。
  • @Ry 感谢您的回复我对 nodejs 有点陌生。但是,如果这是真的,为什么我无法捕捉到错误?并且当出现错误时,promise 是否返回拒绝?

标签: javascript node.js exception-handling try-catch es6-promise


【解决方案1】:

您的requestMarketData 函数需要在 JSON 解析失败时导致 promise 被拒绝。现在,它在JSON.parse 处抛出一个错误,并且没有什么可以捕获它(Promise 构造函数只捕获它内部同步抛出的错误)。您可以自己捕捉:

function requestMarketData() {
    return new Promise(function(resolve, reject) {
        request(url, function(err, res, body) {
            if (err) {
                console.log(err);
                return reject(err);
            }
            console.log("GET: " + url);

            var result;

            try {
                result = JSON.parse("<HTML>"); // make JSON.parse fail
            } catch (err) {
                return reject(err);
            }

            return resolve(result);
        });
    });
}

Promise#then 也会为你捕捉到它:

function requestMarketData() {
    return new Promise(function(resolve, reject) {
        request(url, function(err, res, body) {
            if (err) {
                console.log(err);
                return reject(err);
            }

            console.log("GET: " + url);
            return resolve(body);
        });
    }).then(JSON.parse);
}

等效地,使用异步函数:

function requestMarketData() {
    let body = await new Promise(function(resolve, reject) {
        request(url, function(err, res, body) {
            if (err) {
                console.log(err);
                return reject(err);
            }

            console.log("GET: " + url);
            return resolve(body);
        });
    });

    return JSON.parse(body);
}

【讨论】:

  • 哇,这两种方式看起来都干净多了。我是否需要验证body 在第一种方法中是否有错误?或者将.catch() 放在then 之后就足够了?
  • @quartaela:你也不需要这样做。 .then() 将抛出的错误转换为 rejected 承诺,因此带有trygetMarketData 将捕获它(因为await 将被拒绝的承诺转换回抛出的错误)。
  • 非常感谢瑞!我肯定明白了。最后一个问题,如果你不介意的话。当您发送JSON.parse 时,我如何在then 块内编辑从它返回的对象。或者有没有办法做到这一点?假设我想到达像body.result这样的领域
  • @quartaela:您可以添加另一个.then(data =&gt; data.result) 来转换第一个.then 的结果。
猜你喜欢
  • 2018-07-19
  • 2018-06-01
  • 1970-01-01
  • 2018-11-18
  • 2014-12-29
  • 2014-10-29
  • 2015-07-29
  • 1970-01-01
  • 2016-03-02
相关资源
最近更新 更多