JS:复杂的承诺链

时间:2019-01-09 14:26:11

标签: javascript promise es6-promise

当尝试使用Promises和回调链接复杂的函数调用时,我遇到了一个小问题。

我有一个主函数,该函数调用子例程。在这些例程中,进行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
    })
}

但是当我执行此示例时,将在doAPICall1仍在运行的同时执行doAPICall2。
它仅在进行长时间运行的呼叫时发生。

有人可以给我提示吗?谢谢!

2 个答案:

答案 0 :(得分:1)

别担心,请花一些时间更好地了解Promises。在下面的示例代码中,doAPICall函数返回一个Promise,该Promise解析为一个值,而不是值本身。


    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(...)
    }

答案 1 :(得分:1)

您正在手动做Promises已经为您做的许多事情: axios.get已经返回了Promise,因此在解析时返回响应并在拒绝时返回false毫无意义。 Promise链末尾的catch处理程序已经处理了该链中可能出现的所有错误,因此您不需要catch每个Promise。

我会做类似的事情:

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调用。 (而且,由于Promises的工作方式,如果第一个呼叫失败,第二个呼叫将不会触发。)

为了获得更精细的错误控制,您可能希望在每个Promise之后都进行捕获,以便添加一些额外的日志,例如:

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返回)调用根本不清楚,您需要这种控制机制。

免责声明

此答案无法回答您的代码为何如此运行。但是,代码中有太多错误,因此我认为为您提供有关使用Promises的示例更有价值。