使用回调进行多次顺序调用会导致回调地狱

时间:2016-06-30 10:02:40

标签: javascript callback

我有一个用于通过TCP / IP套接字与服务器通信的函数。每次将命令写入服务器时,都必须等待响应。我编写了一个工作正常的函数,看起来像这样:

function sendCommand(command, callback)
{
    // send command and wait for server to respond...
    // if response was ok
    callback(response, null);
    // if response was bad
    callback("", error);
}

这个问题是我想向服务器发送命令序列,根据答案是什么,我要么继续执行下一个命令,要么处理错误而不发送任何其他命令。

目前我使用此功能:

sendCommand("first command to server", function(response, error)
{
    if(error)
    {
        // handle error
    }
    else
    {
        sendCommand("second command to server", function(response, error)
        {
            //etc..
        }
    }
}

当进行许多顺序调用时,这会导致回调地狱。如果我收到错误,有没有办法让条件调用链中断?类似的东西:

sendCommand("command1", function(){})
.sendCommand("command2", function(){})
.sendCommand("command3", function(){})
.sendCommand("command4", function(){});

例如,如果command2收到错误,则永远不会执行command3和command4调用。

1 个答案:

答案 0 :(得分:3)

您可能需要查看Promises而不是使用callbacks

function sendCommand(command) {
  return new Promise(function(resolve, reject) {
    if(Math.random() > 0.6) {
      reject("Command " + command + " failed.");
    } else {
      resolve("Command " + command + " succeeded");
    }
  });
}

sendCommand("command1")
.then(function(data) {
  console.log(data); //Data from command1
  return sendCommand("command2");
})
.then(function(data) {
  console.log(data); //Data from command2
  return sendCommand("command3");
})
.then(function(data) {
  console.log(data); //Data from command3
  return sendCommand("command4");
})
.then(function(data) {
  console.log(data); //Data from command4
})
.catch(function(error) {
  console.log(error); //Error from any command
});

Fiddle

更新1

根据失败的示例处理错误:

function sendCommand(command) {
  return new Promise(function(resolve, reject) {
    if(Math.random() > 0.6) {
      reject({ command: command, msg: "Command " + command + " failed."});
    } else {
      resolve("Command " + command + " succeeded");
    }
  });
}

sendCommand("command1")
.then(function(data) {
  console.log(data); //Data from command1
  return sendCommand("command2");
})
.then(function(data) {
  console.log(data); //Data from command2
  return sendCommand("command3");
})
.then(function(data) {
  console.log(data); //Data from command3
  return sendCommand("command4");
})
.then(function(data) {
  console.log(data); //Data from command4
})
.catch(function(error) {
  switch(error.command) {
    case "command1":
      //Handle command1 error
      break;
    case "command2":
      //Handle command1 error
      break;
    case "command3":
      //Handle command1 error
      break;
    case "command4":
      //Handle command1 error
      break;
  }
  console.log(error.msg); //Error message from any command
});

Fiddle