Javascript JS:复杂承诺链

Javascript JS:复杂承诺链,javascript,promise,es6-promise,Javascript,Promise,Es6 Promise,在尝试将复杂函数调用与承诺和回调链接起来时,我遇到了一个小问题 我有一个主函数,它调用子例程。在这些例程中进行API调用 例如: function handle(){ new Promise(function(resolve, reject){ let result = doAPICall1() if (result === true) resolve(true); reject(JSON.stringify(result)) })

在尝试将复杂函数调用与承诺和回调链接起来时,我遇到了一个小问题

我有一个主函数,它调用子例程。在这些例程中进行API调用

例如:

function handle(){
    new Promise(function(resolve, reject){
        let result = doAPICall1()
        if (result === true) resolve(true);
        reject(JSON.stringify(result))
    }).then(function(){
        let result = doAPICall2()
        if (result === true) return true
        throw new Error(JSON.stringify(result))
    }).catch(error){
        console.error(JSON.stringify(error))
    }
}
function doAPICall1(){
    axios.get('...').then(function(){
        return true
    }).catch(function(error){
        return error
    })
}

function doAPICall2(){
    axios.get('...').then(function(){
        return true
    }).catch(function(error){
        return error
    })
}
但是当我执行这个示例时,doAPICall2将被执行,而doAPICall1仍在运行。
它仅在进行长时间运行的调用时发生


有人能给我一个提示吗?谢谢大家!

别担心,花点时间更好地理解承诺。在下面的示例代码中,
doAPICall
函数返回解析为值的承诺,而不是值本身


    function handle() {
        doAPICall().then(result => {
            //do something with the result
        }).catch(error => {
            //catch failed API call
            console.error(error)
        }) 
    }

    doAPICall() {
        // this returns a Promise
        return axios.get(...)
    }

不要担心,花点时间更好地理解承诺。在下面的示例代码中,
doAPICall
函数返回解析为值的承诺,而不是值本身


    function handle() {
        doAPICall().then(result => {
            //do something with the result
        }).catch(error => {
            //catch failed API call
            console.error(error)
        }) 
    }

    doAPICall() {
        // this returns a Promise
        return axios.get(...)
    }

您手动完成了很多承诺已经为您完成的事情:
axios.get
已经返回了一个承诺,因此在解析时返回响应没有意义,在拒绝时返回一个
false
。承诺链末尾的
catch
处理程序已经处理了链中可能出现的所有错误,因此您不需要
catch
每个承诺

我会这样做:

function doAPICall1(){
  return axios.get('...');
}

function doAPICall2(){
  return axios.get('...');
}

function handle(){
  // in case you would use the api calls results.
  let firstResult = null;
  let secondResult = null;
  return doAPICall1()
  .then(res => {firstResult = res})
  .then(() => doAPICall2())
  .then(res => {
    secondResult = res;
    return []
   })
}
我想你会用Api调用结果做点什么。使用上面的代码,您可以使用
handle()
函数,如下所示:

function someSortOfController(){
  handle().then(results => {
    console.log(results[0]); // first api call result
    console.log(results[1]); // second api call result
  })
  .catch(err => {
    // here you will find any error, either it fires from the first api call or from the second.
    // there is *almomst* no point on catch before
    console.log(err);
  })
}
在那里,您将访问任何错误,无论是来自第一个api调用还是第二个api调用。(而且,由于承诺是如何运作的,如果第一次呼叫失败,第二次呼叫将不会启动)

为了实现更细粒度的错误控制,您可能希望捕获每个承诺之后的内容,以便添加一些额外的日志,如:

function doAPICall1(){
  return axios.get('...')
  .catch(err => {
    console.log('the error came from the first call');
    throw err;
  });
}

function doAPICall2(){
  return axios.get('...')
  .catch(err => {
    console.log('the error came from the second call');
    throw err;
  });
}
现在,如果第一个api调用失败,一切都会像以前一样工作(因为您在
catch
中再次抛出错误),但是您对错误处理有更多的控制(可能api调用返回的错误根本不清楚,您需要这种控制机制)

免责声明
这个答案不能回答为什么你的代码会这样做。但是,您的代码中有太多错误,因此我认为为您提供一个使用承诺的示例更有价值。

您手动完成了承诺已经为您完成的许多事情:
axios.get
已经返回了一个承诺,因此在解析时返回响应没有意义,在拒绝时返回一个
false
。承诺链末尾的
catch
处理程序已经处理了链中可能出现的所有错误,因此您不需要
catch
每个承诺

我会这样做:

function doAPICall1(){
  return axios.get('...');
}

function doAPICall2(){
  return axios.get('...');
}

function handle(){
  // in case you would use the api calls results.
  let firstResult = null;
  let secondResult = null;
  return doAPICall1()
  .then(res => {firstResult = res})
  .then(() => doAPICall2())
  .then(res => {
    secondResult = res;
    return []
   })
}
我想你会用Api调用结果做点什么。使用上面的代码,您可以使用
handle()
函数,如下所示:

function someSortOfController(){
  handle().then(results => {
    console.log(results[0]); // first api call result
    console.log(results[1]); // second api call result
  })
  .catch(err => {
    // here you will find any error, either it fires from the first api call or from the second.
    // there is *almomst* no point on catch before
    console.log(err);
  })
}
在那里,您将访问任何错误,无论是来自第一个api调用还是第二个api调用。(而且,由于承诺是如何运作的,如果第一次呼叫失败,第二次呼叫将不会启动)

为了实现更细粒度的错误控制,您可能希望捕获每个承诺之后的内容,以便添加一些额外的日志,如:

function doAPICall1(){
  return axios.get('...')
  .catch(err => {
    console.log('the error came from the first call');
    throw err;
  });
}

function doAPICall2(){
  return axios.get('...')
  .catch(err => {
    console.log('the error came from the second call');
    throw err;
  });
}
现在,如果第一个api调用失败,一切都会像以前一样工作(因为您在
catch
中再次抛出错误),但是您对错误处理有更多的控制(可能api调用返回的错误根本不清楚,您需要这种控制机制)

免责声明
这个答案不能回答为什么你的代码会这样做。但是,您的代码中有很多错误,因此我认为为您提供一个使用承诺的示例更有价值。

在doAPICall1函数中,您应该返回承诺。在
doAPICall1
中,您可以返回@ChouW提到的承诺,或者在
中调用
doAPICall2
。然后在doAPICall1函数中调用
doAPICall1
,您应该返回一个承诺。在
doAPICall1
中,您可以返回@ChouW提到的承诺,或者在
中调用
doAPICall2
。然后在
doAPICall1
中调用