承诺链接error handling

我正在学习如何在没有库的情况下使用Promise。 从我所读到的,我可以将Promise链接在一起,然后添加.catch来处理错误。

我期望什么

所以,如果我把URL改成一些错误的URL,我不应该捕捉错误,并停止整个程序继续?

我现在看到了什么?

当我把一个错误的url,程序只是抛出一个错误,而不是像拒绝处理它。

 const request = require("request"); new Promise((resolve, reject) => { request( "http://maps.googleapis.com/maps/api/geocode/json?address=321%20i%20st%20davis", (err, res, body) => { if (err) { reject("bad call on geo code!"); } resolve(JSON.parse(body).results[0].geometry.location); } ); }) .then(res => { const {lat, lng} = res; return new Promise((resolve, reject) => { request( `https://api.darksky.net/forecast/6fb416a8313aabd902a22558e07cc032/${lat},${lng}`, (err, res, body) => { if (err) { reject("bad call on darksky"); } resolve(JSON.parse(body)); } ); }); }) .then(res => { const currentTemp = res.currently.temperature; const feelTemp = res.currently.apparentTemperature; const temps = {currentTemp, feelTemp}; return new Promise((resolve, reject) => { request( "http://ron-swanson-quotes.herokuapp.com/v2/quotes", (err, res, body) => { if (err) { reject("bad call on quotes"); } resolve({temps, body}); } ); }); }) .then(res => { console.log( `Today's weather is ${res.temps.currentTemp}, and it feels like ${res .temps .feelTemp}! \nAnd here is your stupid quote of the day: \n${JSON.parse( res.body )[0]}` ); }) .catch(err => { console.log(err); }); 

错误信息:

这并不是真正有意义,基本上这个错误并没有阻止程序,它只是传递给下一个承诺。 该承诺接收到的错误,但不能parsing它,因为它不是在预期的JSON格式。

 SyntaxError: Unexpected token < in JSON at position 0 at JSON.parse (<anonymous>) at Promise.then.then.then.res (/Users/leoqiu/reacto/playground/6_promiseMethod.js:48:74) at <anonymous> at process._tickCallback (internal/process/next_tick.js:188:7) 

当你在你的if语句中调用reject() ,你不会返回,所以你不使用elseresolve(JSON.parse(body).results[0].geometry.location); 仍然得到执行,并引发exception。

你可以改变这个:

 new Promise((resolve, reject) => { request( "http://maps.googleapis.com/maps/api/geocode/json?address=321%20i%20st%20davis", (err, res, body) => { if (err) { reject("bad call on geo code!"); return; } resolve(JSON.parse(body).results[0].geometry.location); } ); }) 

人们认为reject()工作原理像break或其他控制stream语句是一个常见的错误,因为reject()是一种promise控制stream。 但是,它并不会停止执行,所以你需要return它或使用else

或者,我更喜欢使用if/else因为我认为它使逻辑更加明显:

 new Promise((resolve, reject) => { request( "http://maps.googleapis.com/maps/api/geocode/json?address=321%20i%20st%20davis", (err, res, body) => { if (err) { reject("bad call on geo code!"); } else { resolve(JSON.parse(body).results[0].geometry.location); } } ); }) 

基于帕特里克·埃文斯的build议…

reject不停止程序运行,所以错误消息传递到下一个Promise,这就是为什么抛出一个jsonparsing错误。

解决方法是简单地把拒绝的return

 if (err) { reject("bad call on geo code!"); return err; }