Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jsp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用异步代码引发/捕获错误的替代方案?_Javascript_Node.js_Exception_Asynchronous_Callback - Fatal编程技术网

Javascript 使用异步代码引发/捕获错误的替代方案?

Javascript 使用异步代码引发/捕获错误的替代方案?,javascript,node.js,exception,asynchronous,callback,Javascript,Node.js,Exception,Asynchronous,Callback,我习惯于抛出某个错误类的实例,并让它们在应用程序中的某个位置被捕获,以解释用户错误 验证用户名可能是一个示例: function validateUsername (username) { if (!/^[a-z0-9_-]{3,15}$/.test(username)) { throw new ValidationError('Please enter 3-15 letters, digits, -, and/or _.'); } } $('#username

我习惯于抛出某个错误类的实例,并让它们在应用程序中的某个位置被捕获,以解释用户错误

验证用户名可能是一个示例:

function validateUsername (username) {
    if (!/^[a-z0-9_-]{3,15}$/.test(username)) {
        throw new ValidationError('Please enter 3-15 letters, digits, -, and/or _.');
    }
}

$('#username').blur(function () {
    try {
        validateUsername($(this).val());
    } catch (x) {
        $('<p></p>').addClass('error').text(x).insertAfter(this);
    }
});
我可以让
checkUsernameAvailability
接受回调和/或返回承诺,并让它使用用户名的可用性执行上述回调

$('#username').blur(function () {
    checkUsernameAvailability(username, function (available) {
        !available && alert('The username you entered is already in use.');
    });
});
但异常之所以如此强大,部分原因是它们可以在堆栈中冒泡,直到被捕获,而如果我有另一个函数调用另一个名为
checkUsernameAvailability
的函数,我需要一直手动传递回调的结果,直到到达我想要处理它的地方

向堆栈上传递错误的替代方法有哪些?我可以想到其中一些,但没有一个像本机异常那样干净:

  • 将标志或ValidationError实例传递给回调(Node.js方法也可以工作,将错误或null作为第一个参数传递,将数据作为第二个参数传递);但是,如果我不想在堆栈中的那个点处理它,我需要手动传递错误
  • 或者将两个回调传递给
    checkUsernameAvability
    函数,一个成功回调和一个错误回调;这似乎与前一点有相同的缺点
  • 触发一个“ValidationError”事件,这样我就可以在任何地方监听,但要确保
    返回false,这样它就不会在堆栈的更高位置执行;但是,这会污染事件名称空间,并可能导致不清楚将首先执行哪个事件侦听器;另外,使用控制台很难跟踪事件的起源

  • 原则上是这样的

    function Exception (errcode) {
      this.code = errcode;
    }
    
    ...
    
    try {
      ...
      throw new Exception('alpha');
      ...
    } catch (e) {
      if (e.code === {something}) {
      }
    }
    

    如果有帮助的话,我最近用C编写了第一个为UNIX编写的Rogue游戏,并将其改写为javascript,以便在浏览器中工作。我使用了一种称为continuation的技术来等待用户输入密钥,因为在javascript中没有中断

    所以我会有这样一段代码:

    void function f() {
    
      // ... first part
    
      ch = getchar();
    
      // ... second part
    
    }
    
    这将在未来发生变化

    function f() {
    
      // ... first part
    
      var ch = getchar(f_cont1);
    
      return;
      // the execution stops here 
    
      function f_cont1 () {
    
        // ... second part
      }
    }
    

    然后将继续存储起来,以便在按键事件中重用。有了闭包,一切都会在停止的地方重新开始。

    这就是承诺的意义所在。有许多库允许您在ES5中使用它们。传递给“done”的函数具有保留“username”的闭包,那么问题出在哪里?
    function f() {
    
      // ... first part
    
      var ch = getchar(f_cont1);
    
      return;
      // the execution stops here 
    
      function f_cont1 () {
    
        // ... second part
      }
    }