Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/418.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_Exception_Asynchronous_Promise_Redux - Fatal编程技术网

Javascript 复杂承诺-返回链中的承诺-捕获()顺序

Javascript 复杂承诺-返回链中的承诺-捕获()顺序,javascript,exception,asynchronous,promise,redux,Javascript,Exception,Asynchronous,Promise,Redux,当我从函数a向函数B返回一个承诺,然后从函数a返回数据,并且两个调用都遵守承诺时,错误是如何捕获的?我知道,当承诺得到解决时,A总是首先执行,然后是B,然后是A返回的数据。但是,当这种承诺的回报形成一条长长的链条时,我无法理解错误是如何被抓住的。下面是该场景的简化示例。我正在使用Redux thunk动作创建者来管理状态 function postActionCreator(data) { return (dispatch) => { dispatch(type: POST_L

当我从函数a向函数B返回一个承诺,然后从函数a返回数据,并且两个调用都遵守承诺时,错误是如何捕获的?我知道,当承诺得到解决时,A总是首先执行,然后是B,然后是A返回的数据。但是,当这种承诺的回报形成一条长长的链条时,我无法理解错误是如何被抓住的。下面是该场景的简化示例。我正在使用Redux thunk动作创建者来管理状态

function postActionCreator(data) {
  return (dispatch) => {
    dispatch(type: POST_LOADING)
    return Source.post()
      .then(response => {
        dispatch(type: POST_SUCCESS, payload: response)
        return response
      })
      .catch(error => {
        // Is this catch called if handlePost throws error in then?
        dispatch(type: POST_ERROR, payload: error)
        throw new Error(error)
      })
  }
}

// Container component's post function calling the Redux action creator
function handlePost(data) {
  this.props.postActionCreator(data)
    .then(response => {
      // Do something with response
    })
    .catch(error => {
      // Or is the error caught with this catch?
    })
}

// Or are the both catchs called, in which order and why?
在这三种不同的情况下如何处理错误:

  • Source.post抛出和错误
  • postActionCreator然后抛出一个错误
  • 然后handlePost会抛出一个错误

使用承诺时,函数应执行以下三项操作之一:

  • 返回一个值
  • 还愿
  • 出错
  • 对于这个问题,我们不太关心前两个案例,但您可以在这里阅读更多信息。让我们来看看这个错误的例子。

    在JavaScript中,错误——就像大多数事情一样——只是对象。创建错误和选择如何传播错误是两件不同的事情。传播错误的两大类是同步和异步的。要同步传播错误,您必须抛出它,对于async,您只需通过一些预定义的约定(例如回调或承诺)传递错误对象

    为了充分回答这个问题,我们需要了解如何处理这两种不同的错误类型。对于同步错误(已抛出),处理它们的唯一方法(除了像
    window.onerror这样的catch-all事件处理程序之外)是将它们包装在
    try/catch
    语句中。对于异步错误,我们只需遵循如何将此数据传递回调用堆栈的约定

    因此,要用这些知识回答您的问题:

    Source.post抛出错误

    如果我假设“抛出一个错误”,您的意思是“发生了一个错误”,那么在不知道
    source.post的源代码的情况下,我们无法知道这将如何进行。如果确实抛出了一个错误,比如说出现了一些意外的
    ReferenceError
    ,那么实际上根本不会处理它:

    function post() {
      foo.bar; // will throw
    }
    
    function run() {
      post()
        .then(log)
        .catch(log);
    }
    
    将导致:

    ReferenceError: foo is not defined
        at post (sync.js:6:3)
        at run (sync.js:10:3)
        at Object.<anonymous> (sync.js:15:1)
    
    导致

    捕获错误:foo

    更有趣的是,您的代码在
    catch
    语句中实际上抛出了一个新的
    Error
    对象。在这种情况下,我们还有最后一件事需要了解。我们知道同步抛出一个错误意味着必须捕获它,但是从
    然后
    函数中抛出一个错误会导致一个被拒绝的异常,而不是一个错误,那么发生了什么呢?好的,promise实现在内部将传递给
    然后
    的函数包装在
    try/catch
    块中,然后通过拒绝promise来处理此错误。我们可以这样证明:

    function post() {
      return new Promise((resolve, reject) => {
        resolve('foo');
      });
    }
    
    function run() {
      post()
        .then((result) => {
          throw result;
        })
        .catch((err) => {
          console.error('Caught error:', err);
        });
    }
    
    在这种情况下,也会捕获错误

    postActionCreator随后抛出一个错误

    这现在变得很简单。捕获并传播
    中的错误,然后
    。它到达
    postActionCreator
    内的
    catch
    ,然后返回到外部
    catch

    handlePost会抛出一个错误

    最简单的情况。它将在内部捕获,然后在
    之后立即在
    catch
    语句中得到错误



    最后,您可能会想,“如何处理
    Source.post
    中的同步错误?如果这不是我的功能呢?”。好问题!您可以使用Bluebird之类的实用程序为您包装此函数。

    使用承诺时,函数应执行以下三项操作之一:

  • 返回一个值
  • 还愿
  • 出错
  • 对于这个问题,我们不太关心前两个案例,但您可以在这里阅读更多信息。让我们来看看这个错误的例子。

    在JavaScript中,错误——就像大多数事情一样——只是对象。创建错误和选择如何传播错误是两件不同的事情。传播错误的两大类是同步和异步的。要同步传播错误,您必须抛出它,对于async,您只需通过一些预定义的约定(例如回调或承诺)传递错误对象

    为了充分回答这个问题,我们需要了解如何处理这两种不同的错误类型。对于同步错误(已抛出),处理它们的唯一方法(除了像
    window.onerror这样的catch-all事件处理程序之外)是将它们包装在
    try/catch
    语句中。对于异步错误,我们只需遵循如何将此数据传递回调用堆栈的约定

    因此,要用这些知识回答您的问题:

    Source.post抛出错误

    如果我假设“抛出一个错误”,您的意思是“发生了一个错误”,那么在不知道
    source.post的源代码的情况下,我们无法知道这将如何进行。如果确实抛出了一个错误,比如说出现了一些意外的
    ReferenceError
    ,那么实际上根本不会处理它:

    function post() {
      foo.bar; // will throw
    }
    
    function run() {
      post()
        .then(log)
        .catch(log);
    }
    
    将导致:

    ReferenceError: foo is not defined
        at post (sync.js:6:3)
        at run (sync.js:10:3)
        at Object.<anonymous> (sync.js:15:1)
    
    导致

    捕获错误:foo

    更有趣的是,您的代码在
    catch
    语句中实际上抛出了一个新的
    Error
    对象。在这种情况下,我们还有最后一件事需要了解。我们知道同步抛出一个错误意味着必须捕获它,但是从
    然后
    函数中抛出一个错误会导致一个被拒绝的异常,而不是一个错误,那么发生了什么呢?promise实现在内部将传递给
    的函数包装到
    try/catch
    块中,然后处理此错误