如何在出错时打破承诺链

时间:2016-01-12 16:03:56

标签: javascript node.js promise

考虑这个片段

fetch(`http://${api.host}:${api.port}/user`)
  .then(function(data) {
    return data.json();
  }, function(err) {
    throw new Error(`Couldn\'t fetch user data from server: ${err.message}`);
  }).then(function(eparkUser) {
    for (var key in eparkUser) {
      if (eparkUser.hasOwnProperty(key) && !user.hasOwnProperty(key)) {
        user[key] = eparkUser[key];
      }
    }
    done(null, user);
  }, function(err) {
    throw new Error(`Couldn't parse returned json: ${err.message}`);
  }).catch(function(e) {
    done(e);
  });

throw是不是应该打破链并触发.catch?如何实现这种行为?现在两个throw正在执行,我看到消息:

Error: Couldn't parse returned json: Couldn't fetch user data from server: request to http://localhost:3010/user failed这不是我想要的。

P.S。 fetch是npm node-fetch模块

1 个答案:

答案 0 :(得分:3)

不,throw不会跳转到catch。它拒绝承诺,并且将调用安装在其上的所有错误处理程序。在您的情况下,这是then调用安装的错误处理程序。请注意,.catch(handler)只是.then(null, handler)的糖。

您当前的代码就像

一样
try {
    try {
        try {
            var data = fetch(`http://${api.host}:${api.port}/user`)
        } catch(err) {
            throw new Error(`Couldn\'t fetch user data from server: ${err.message}`);
        }
        var eparkUser = data.json();
    } catch(err) {
        throw new Error(`Couldn't parse returned json: ${err.message}`);
    }
    for (var key in eparkUser) {
        if (eparkUser.hasOwnProperty(key) && !user.hasOwnProperty(key)) {
            user[key] = eparkUser[key];
        }
    }
    done(null, user);
} catch(e) {
    done(e);
}

要解决您的问题,您需要嵌套处理程序,并仅在该特定承诺上安装JSON-parse-handler:

fetch(`http://${api.host}:${api.port}/user`)
    .then(function (data) {
        return data.json()
            .then(function (eparkUser) {
                for (var key in eparkUser) {
                    if (eparkUser.hasOwnProperty(key) && !user.hasOwnProperty(key)) {
                        user[key] = eparkUser[key];
                    }
                }
                return user;
            }, function(err) {
                throw new Error(`Couldn't parse returned json: ${err.message}`);
            });
    }, function(err) {
        throw new Error(`Couldn\'t fetch user data from server: ${err.message}`);
    })
    .then(done.bind(null, null), done);