Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/36.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何处理Node.js中基于承诺的业务级函数返回的对象出错?_Javascript_Node.js_Express_Promise_Node Fetch - Fatal编程技术网

Javascript 如何处理Node.js中基于承诺的业务级函数返回的对象出错?

Javascript 如何处理Node.js中基于承诺的业务级函数返回的对象出错?,javascript,node.js,express,promise,node-fetch,Javascript,Node.js,Express,Promise,Node Fetch,我需要创建一个名为“getLocationById”的业务级函数,该函数通过RESTAPI从远程服务器检索一些数据。然后,路由器调用此函数以在网页上显示数据 如果fetch调用成功,json结果将作为Promise返回。但是,如果fetch发现错误,例如远程服务器没有响应或响应错误为500,则应向路由器返回什么 此外,路由如何响应错误 const fetch = require('node-fetch'); const p_conf = require('../parse_config'

我需要创建一个名为“getLocationById”的业务级函数,该函数通过RESTAPI从远程服务器检索一些数据。然后,路由器调用此函数以在网页上显示数据

如果fetch调用成功,json结果将作为Promise返回。但是,如果fetch发现错误,例如远程服务器没有响应或响应错误为500,则应向路由器返回什么

此外,路由如何响应错误

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
(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.
然后(r=>res.send(r.json())

进一步编辑:

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));
        })
    }
};
然后我做了以下修改

业务层

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);
  })  
});
然后抛出一个新错误:

TypeError: Cannot read property 'then' of undefined
(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.
(节点:10184)未处理的PromisejectionWarning:TypeError:正文已用于:http://localhost:1337/parse/classes/GCU
R_位置
在Response.consumerbody(C:\Work\tmp\node\u modules\node fetch\lib\index.js:326:30)
在Response.json(C:\Work\tmp\node\u modules\node fetch\lib\index.js:250:22)
在db_location.getLocations.then.r(C:\Work\tmp\ExpressApps\expressparse server\routes\locations.js:30:13)
在
在进程中。_tickDomainCallback(internal/process/next_tick.js:228:7)
(节点:10184)未处理的PromisejectionWarning:未处理的承诺拒绝。此错误源于
没有catch块的异步函数的ide,或拒绝未使用.catch()处理的承诺。(拒绝
编号:5)
(节点:10184)[DEP0018]弃用警告:未处理的承诺拒绝已弃用。在未来,承诺拒绝
未处理的将使用非零退出代码终止Node.js进程。

我相信fetch函数返回了一个Promise对象,调用函数可以从路由接收到该对象?

如果出现故障或错误,系统需要执行以下操作:

  • 注册错误
  • 确定错误类型
  • 操作错误,例如无法连接到服务器
  • 程序员错误,这是错误,需要由开发人员修复
  • 操作错误可以被忽略

  • 单元测试
  • 处理异步和同步调用
  • 确保未将所有参数传递给函数
  • 检查空参数(如果为false)将显示一个错误,要求用户提供必需的字段
  • 如果服务器未连接,系统应在间隔60秒后重试

    编程错误:

    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));
            })
        }
    };
    
    • 用“throw”终止函数
    • 记录错误
    • 向用户显示适当的消息,而不使用任何技术术语

    如果您的错误需要路由器处理,您需要在
    getLocationById
    中不执行
    catch()
    或在那里执行
    catch()
    操作,处理您需要的内容,然后返回
    Promise.reject(error)
    ,这样路由器仍然可以在下游处理它

    比如:

    函数getLocation(){ return Promise.reject('some error')//fake fetch error .然后(r=>r) .catch(错误=>{ console.log(“getlocation中的处理错误”)//可能是日志或其他函数 返回承诺。拒绝(错误) }) } //路线: getLocation() .then(r=>console.log(“发送给用户”))
    .catch(error=>console.log(“向用户发送错误:”,error))您的新编辑即将完成!首先,让我们澄清一个关于你的误解。非OK响应不会导致拒绝获取承诺。要确定呼叫是否有成功响应,请检查

    接下来,我们需要研究该方法。查看文档,我们发现它还返回一个承诺,而不是JSON

    这是一款更接近您所需的路由器版本:

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

    我认为你学习承诺是件好事。一旦你对承诺感到满意,就退房吧。这将使您的代码更易于阅读,但了解承诺很重要。

    尝试切换到以下代码,并告诉我它是否有效:

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

    如果出现错误,您希望发生什么?它应该向用户报告什么吗?@MarkMeyer是的,错误消息应该返回给路由器,然后路由器应该处理该消息并打印给前端用户。谢谢。但是在我修改后抛出了一个错误。请参阅我对该问题的编辑。@alextc您似乎没有从
    getLocations()
    返回任何内容。我想你需要
    Fetch()
    的承诺。谢谢@Mark。我做了一些相关的改变。请参考进一步的编辑。函数返回“fetch”,它根据节点fetch文档返回一个Promise对象。