【问题标题】:What is the appropriate way to handle an async error within a promise?在 Promise 中处理异步错误的适当方法是什么?
【发布时间】:2016-03-23 13:27:20
【问题描述】:

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

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)。我希望拒绝使用从该命令返回的响应,这是我必须在现有承诺中运行的另一个异步操作。

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

【问题讨论】:

  • 从循环内部调用 resolvereject 很奇怪。
  • 是的,它或多或少只是跳过不是成功或失败的消息。例如,如果您使用MG "Hello",它将输出Hello\r\n:\r\n,而Hello\r\n 只是略过

标签: javascript asynchronous promise bluebird


【解决方案1】:

你不必在承诺。你可以在 promise 之后链接一个.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);
    });
  });
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-13
    • 2015-08-19
    • 1970-01-01
    • 1970-01-01
    • 2022-01-13
    相关资源
    最近更新 更多