如何在Node.js中基于Promise的业务级函数中处理Error上返回的对象? [英] How to deal with returned object on Error in a Promise-based business-level function in Node.js?

查看:252
本文介绍了如何在Node.js中基于Promise的业务级函数中处理Error上返回的对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要创建一个名为"getLocationById"的业务级别功能,该功能通过REST API从远程服务器中检索一些数据.然后,路由器会调用此功能以在网页上显示数据.

I need to create a business level function called "getLocationById" which retrieves some data from a remote server via REST API. This function is then called by a router to display the data on a web page.

如果获取调用成功,则将json结果作为Promise返回.但是,如果抓取出现错误(例如,远程服务器没有响应或没有响应500错误?

If the fetch call is successful, the json result is returned as Promise. However, what should be returned to the router if fetch caught an error, e.g. remote server was not responding or responding with a 500 error?

此外,路线如何响应错误?

Furthermore, how does the route respond to the error?

const fetch = require('node-fetch');    
const p_conf = require('../parse_config');  // Configuration

const db = {
    getLocationById: function(locId) {
        fetch(`${p_conf.SERVER_URL}/parse` + '/classes/location', { method: 'GET', headers: {
            'X-Parse-Application-Id': p_conf.APP_ID,
            'X-Parse-REST-API-Key': p_conf.REST_API_KEY
        }})
        .then(res1 => return res1.json())  // RETURN A PROMISE ON SUCCESS
        .catch((error) => {
            console.log(error);
            **WHAT TO RETURN TO THE ROUTER ON ERROR HERE?**
        });
    }
};

const db_location = {
    getLocations: function() {
        //res.send("respond with 'locations' router.");
        fetch(`${p_conf.SERVER_URL}/parse` + '/classes/GCUR_LOCATION', { method: 'GET', headers: {
            'X-Parse-Application-Id': p_conf.APP_ID,
            'X-Parse-REST-API-Key': p_conf.REST_API_KEY
        }})
        .then(res1 => res1)
        .catch((error) => {
            console.log(error);
            return Promise.reject(new Error(error));
        })
    }
};

在路由器中:

router.get('/', function(req, res, next) {
  db_location.getLocations()
  .then(r => res.send(r.json()))      // WHERE AN ERROR WAS THROWN
  .catch((err) => {
    console.log(err);
    return next(err);
  })
});

引发了以下错误:

TypeError: Cannot read property 'then' of undefined

.then(r => res.send(r.json()))

进一步的

然后我进行了以下更改.

I then made the following changes.

业务层

getLocations: function() {
    // According to node-fetch documentation, fetch returns a Promise object.
    return fetch(`${p_conf.SERVER_URL}/parse` + '/classes/GCUR_LOCATION', { method: 'GET', headers: {
        'X-Parse-Application-Id': p_conf.APP_ID,
        'X-Parse-REST-API-Key': p_conf.REST_API_KEY
      } });

}

路由器端:

router.get('/', function(req, res, next) {
   db_location.getLocations()
  .then(r => {
    console.log("r.json(): " + r.json());
    res.send(r.json())})
  .catch((err) => {
    console.log(err);
    return next(err);
  })  
});

然后抛出了一个新的错误:

Then a new error was thrown:

(node:10184) UnhandledPromiseRejectionWarning: TypeError: body used already for: http://localhost:1337/parse/classes/GCU
R_LOCATION
    at Response.consumeBody (C:\Work\tmp\node_modules\node-fetch\lib\index.js:326:30)
    at Response.json (C:\Work\tmp\node_modules\node-fetch\lib\index.js:250:22)
    at db_location.getLocations.then.r (C:\Work\tmp\ExpressApps\express-parse-server\routes\locations.js:30:13)
    at <anonymous>
    at process._tickDomainCallback (internal/process/next_tick.js:228:7)
(node:10184) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing ins
ide of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejectio
n id: 5)
(node:10184) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejection
s that are not handled will terminate the Node.js process with a non-zero exit code.

我相信fetch函数返回的Promise对象可以被调用函数从路由中接收到吗?

I believed the fetch function returned a Promise object that can be received by the calling function from the route?

推荐答案

您的新编辑已关闭!首先,让我们澄清一下您对获取的误解. .非OK响应不会导致获取承诺被拒绝.为了确定呼叫是否成功响应,请检查响应.ok .

Your new edits are close! First let's clear up a misconception you have about fetch. Non-OK responses do not result in the fetch promise being rejected. In order to determine if a call has a successful response, check response.ok.

接下来,我们需要调查 json 方法.查看文档,我们发现它还返回一个promise而不是JSON.

Next we need to investigate the json method. Looking at the documentation we see that it also returns a promise and not JSON.

这是您的路由器的一个版本,它与您要寻找的版本更接近:

Here's a version of your router that's a closer to what you're looking for:

router.get('/', function(req, res, next) {
   db_location.getLocations()
   .then(r => {
        if (r.ok) { return r.json(); }
        throw 'Something went wrong!';
    })
   .then(data => res.json(data))
   .catch((err) => {
        console.log(err);
        next(err);
    })  
});

我认为您正在学习诺言真是太好了.一旦您对诺言感到满意,请查看 async/await .它将使您的代码更易于阅读,但了解诺言很重要.

I think it's great that you're learning promises. Once you feel comfortable with promises check out async/await. It'll make your code easier to read but having an understanding of promises is important.

这篇关于如何在Node.js中基于Promise的业务级函数中处理Error上返回的对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆