javascript - Promise 链接错误处理

标签 javascript node.js promise

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

我期望什么

因此,如果我将 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);
  });

错误消息:

这并没有什么意义,基本上错误并没有停止程序,它只是传递给下一个 promise 。该 Promise 收到错误,但无法解析它,因为它不是预期的 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() 时,您不会返回,也不会使用 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() 是一种 Promise 控制流。但是,它不会停止您的 block 中的执行,因此您需要在其后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);
      }
    }
  );
})

关于javascript - Promise 链接错误处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47008070/

相关文章:

javascript - 如何使用 jQuery URI 更新具有完整目录路径的链接?

mysql - node-mysql 仅在两个表合并后提供第一个表的数据

javascript - 将 Promise 用于 onload 和 onerror 后返回状态值

javascript - 干掉 JavaScript 中的 Promise

javascript - 未处理的拒绝 - Promise

javascript - Ajax 在页面上加载

javascript - "Unresolved function or method"与 Passport.JS

javascript - 从数组 Javascript 中删除重复项

javascript - 如何在 AWS DynamoDB 中按排序键查询?

javascript - node.js setTimeout 的替代方案