在promise中处理异步错误的适当方法是什么?

时间:2016-03-23 13:27:20

标签: javascript asynchronous promise bluebird

我遇到了一个奇怪的情况。我有一个函数,它将通过以太网向控制器发送命令并等待响应(其中:表示成功,?表示失败)。这是我目前的代码。

send(command, timeout=5000) {
  let listener = _.noop;
  return new Promise((resolve, reject) => {
    listener = Meteor.bindEnvironment(data => {
      data.split(/\r\n/).forEach(line => {
        if (/^\:$/.test(line)) resolve(command);
        // ** this is where the problem is **
        if (/^\?$/.test(line)) reject(command)
      });
    });
    this.on('data', listener).write(`${command}\r\n`);
  }).timeout(timeout).finally(() => {
    this.removeListener('data', listener);
  })
}

现在,抓住了:

如果我的承诺中出现错误,我将不得不运行另一个命令以获取错误代码(the TC command from this reference)。我希望拒绝使用从该命令返回的响应,这是我必须在现有的promise中运行的另一个异步操作。

在异步代码中执行此操作的正确方法是什么?

1 个答案:

答案 0 :(得分:1)

你不必在里面承诺。您可以在承诺后链接.catch

_send(command, timeout) {
  let listener = _.noop;
  return new Promise((resolve, reject) => {
    listener = Meteor.bindEnvironment(data => {
      data.split("\r\n").forEach(line => {
        if (line == ":") resolve(command);
        if (line == "?") reject(command);
      });
    });
    this.on('data', listener).write(command+"\r\n");
  }).timeout(timeout).finally(() => {
    this.removeListener('data', listener);
  })
}
send(command, timeout=5000) {
  return this._send(command, timeout).catch(err => {
    if (e instanceof Promise.TimeoutError) throw e;
    return this.send("TC1", 500).then(errcode => {
      throw new Error("error code for "+err+": "+errcode);
    }, () => {
      throw new Error("could not fetch error code for "+err);
    });
  });
}