Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/42.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.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 承诺链错误处理_Javascript_Node.js_Promise - Fatal编程技术网

Javascript 承诺链错误处理

Javascript 承诺链错误处理,javascript,node.js,promise,Javascript,Node.js,Promise,我正在学习如何在没有图书馆的情况下使用Promise。从我所读到的内容来看,我可以将Promise链接在一起,然后在最后添加.catch,以进行错误处理 我期望什么 因此,如果我将URL更改为某个错误的URL,我是否应该捕获错误并停止整个程序继续 我现在看到了什么? 当我输入错误的url时,程序只是抛出一个错误,而不是像拒绝一样处理它 const request = require("request"); new Promise((resolve, reject) => { requ

我正在学习如何在没有图书馆的情况下使用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);
  });
错误消息:

这不是真正有意义的,基本上错误没有停止程序,它只是传递给下一个承诺。该承诺接收到错误,但无法解析它,因为它不是预期的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)
SyntaxError:JSON中位置0处的意外标记<
在JSON.parse()处
at Promise.then.then.res(/Users/leoqiu/reacto/playerdy/6_promiseMethod.js:48:74)
在
在进程中。_tick回调(内部/process/next_tick.js:188:7)
当您在
if
语句中调用
reject()
时,您不会返回,也不会使用
else
因此您的
解析(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()
是一种承诺控制流。但是,它不会停止块中的执行,因此您需要在它之后返回
或使用
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);
      }
    }
  );
})
if
语句中调用
reject()
时,不会返回,也不会使用
else
,因此
解析(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()
是一种承诺控制流。但是,它不会停止块中的执行,因此您需要在它之后返回
或使用
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);
      }
    }
  );
})

根据帕特里克·埃文斯的建议

reject
不会停止程序运行,因此错误消息会传递到下一个Promise,这就是抛出
json
解析错误的原因

解决方案就是在拒绝中添加一个
返回值

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

根据帕特里克·埃文斯的建议

reject
不会停止程序运行,因此错误消息会传递到下一个Promise,这就是抛出
json
解析错误的原因

解决方案就是在拒绝中添加一个
返回值

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

错误是什么?这取决于我在哪个阶段更改url,因此基本上拒绝抛出错误,并且错误消息被传递下来,由
res
为下一个承诺处理。因此,该错误只是一个JSON解析错误。此外,还添加了错误inNo,您只需在reject()调用后执行
返回操作。还要注意的是,catch()回调在打印捕获的错误消息时起作用,它只是打印出了您不期望的错误。仅供参考,以使使用承诺进行编码更容易使用。您有3个对
request
的调用,这些调用都是您单独“允诺”的,这很好,因为它们的结果都略有不同。但是,您可以通过创建一个“promisified”
请求
函数来简化此过程。。。看看你的代码有多简单,错误是什么?这取决于我在哪个阶段更改url,所以基本上拒绝抛出错误,并且错误消息被传递下来,由
res
为下一个承诺处理。因此,该错误只是一个JSON解析错误。此外,还添加了错误inNo,您只需在reject()调用后执行
返回操作。还要注意的是,catch()回调在打印捕获的错误消息时起作用,它只是打印出了您不期望的错误。仅供参考,以使使用承诺进行编码更容易使用。您有3个对
request
的调用,这些调用都是您单独“允诺”的,这很好,因为它们的结果都略有不同。但是,您可以通过创建一个“promisified”
请求
函数来简化此过程。。。看看你的代码有多简单