我正在学习如何在没有库的情况下使用Promise。根据我的阅读,我可以将Promise链接在一起,然后在最后添加.catch
以进行错误处理。
我期待什么
因此,如果我将URL更改为某个false 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);
});
错误讯息:
这不是真正有意义的,基本上错误并没有停止程序,这只是传递给下一个承诺。该承诺收到错误但无法解析它,因为它不是预期的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)
答案 0 :(得分:0)
当您在reject()
声明中致电if
时,您将无法返回,并且您没有使用else
,因此您的resolve(JSON.parse(body).results[0].geometry.location);
仍会获得执行并抛出异常。
您可以更改为:
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
或其他一些控制流语句,这是一个常见错误,因为reject()
是一种承诺控制流。但是,它不会在您的区块中停止执行,因此您需要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);
}
}
);
})
答案 1 :(得分:0)
基于Patrick Evans的建议......
reject
不会阻止程序运行,因此错误消息会传递给下一个Promise,这就是为什么抛出json
解析错误的原因。
解决方案只是在拒绝中加上return
。
if (err) {
reject("bad call on geo code!");
return err;
}