Javascript 异步等待和承诺。所有错误处理

Javascript 异步等待和承诺。所有错误处理,javascript,ecmascript-6,Javascript,Ecmascript 6,我必须调用一个api,然后使用响应调用其他api,让我们简化这个问题,假设我们在这种情况下只调用2个api 我的问题: 1。在这种情况下,我不知道如何处理试捕。 2。承诺不会停止,那么我该如何停止呢?(我找到了使用蓝鸟的解决方案)为什么我需要阻止它们?因为他们说这是更多的API,所以继续下去是一种浪费。 我的尝试代码如下 async function getUserFriendsAndFriendOfFriend() { let user = await fetchUser('/users/

我必须调用一个api,然后使用响应调用其他api,让我们简化这个问题,假设我们在这种情况下只调用2个api

我的问题:

1。在这种情况下,我不知道如何处理试捕。

2。承诺不会停止,那么我该如何停止呢?(我找到了使用蓝鸟的解决方案)为什么我需要阻止它们?因为他们说这是更多的API,所以继续下去是一种浪费。

我的尝试代码如下

async function getUserFriendsAndFriendOfFriend() {
  let user = await fetchUser('/users/me')

  let friendsIDs = await fetchJSON(`/friends/${user.id}`) //use user.id as param
  let friend_of_friend_IDs = await fetchJSON(`/friends_of_friends/${user.id}`) //use user.id as param

  //build promises
  let promises = friendIDs.map(id => fetchJSON(`/users/${id}`))
  promises = friend_of_friend_IDs.map(id => fetchJSON(`/users/${id}`))

  try {
    await Promise.all(promises) //is this correct?
  } catch(e) {
    alert(e) // maybe either one promises failed, but it won't stop other from calling
  }
}

getUserFriendsAndFriendOfFriend() // call
我在看这段视频时有这样的想法

我上面的代码实际上是他在26:10分修改的版本。

关于错误处理 我想这取决于您希望如何处理可能发生的错误。您的代码中有错误处理的概念吗

简单地“处理”错误,同时让
getUserFriends和FriendofFriend
假装成功,可能不是最好的方法

就个人而言,我宁愿选择抛出错误,并且方法的使用者应该处理任何可能的错误

当然,您可能希望记录已发生的错误,但仍然应该重新抛出它。如果没有,则使用者无法知道该方法是否失败

如何停止承诺 好吧,在你当前的版本中,你不能真正停止承诺,因为它们都已经在运行了。在映射这两个数组时,您将启动所有这些数组(这将启动内部
获取

Promise.all
最终将完成或失败(注意,在添加到问题中的代码版本中,您将只捕获在
friend\u of friend\u id
数组中发生的错误)

如果您真的想让它们在第一个失败时立即失败,那么您可以通过更改代码为它们构建一个链,如:

await friendIDs
  .concat( friend_of_friend_IDs )
  .reduce( 
    (current, item) => current.then( 
      () => fetchJSON( `/users/${item}` ) ), 
    Promise.resolve( true ) );
这将首先组合两个数组,然后按顺序解析好友列表。一旦其中一个失败,链将停止,不再调用其他承诺

这种方法的一个问题是,您不可能捕获结果,但从理论上讲,您可以用结果填充一个数组,例如以下方式:

let results = [];
return await friendIDs
  .concat( friend_of_friend_IDs ) // concatenate the 2 arrays
  .reduce( (current, item) => current.then( // chain the promise
    () => fetchJSON( `/users/${item}` )
      .then( response => results.push( response ) ) // handle the results
    ), 
    Promise.resolve( true ) ) // start with a default promise
  .then( () => results ); // return the results
现在,
结果
将包含找到的所有好友,并将分发给方法的使用者。任何引发的错误都必须由使用者处理,因此最终的代码看起来类似于

async function getUserFriendsAndFriendOfFriend() {
  let user = await fetchUser('/users/me');

  let friendsIDs = await fetchJSON(`/friends/${user.id}`);
  let friend_of_friend_IDs = await fetchJSON(`/friends_of_friends/${user.id}`);

  let results = [];
  return await friendIDs
    .concat( friend_of_friend_IDs ) // concatenate the 2 arrays
    .reduce( (current, item) => current.then( // chain the promise
      () => fetchJSON( `/users/${item}` )
        .then( response => results.push( response ) ) // handle the results
      ), 
      Promise.resolve( true ) ) // start with a default promise
    .then( () => results ); // return the results
}

getUserFriendsAndFriendOfFriend()
  .then( results => {
    // results contains all the responses from the calls to fetchJSON with users id
  })
  .catch( err => {
    // error will show you what went wrong with the single request, no other results will be returned
  });

你能描述一下你希望发生什么吗?(承诺应该在哪里停止或哪些承诺没有缓存?是的,
async
/
await
使用try-catch来捕获错误。如果您真的想在一个错误发生后停止,您必须
等待它,而不是创建
FriendsID
映射。请注意,您的第二个映射将替换它。)他是第一个,所以电话已经运行了很长时间。你的
等待
承诺。所有的
只会在朋友的朋友地图上等待。所以,我想说的是,如果在给朋友打电话时发生错误,它不会被捕获,只有朋友的朋友可能发生的错误才会被捕获只有朋友才会被捕获如果朋友请求被替换,则会出现朋友数。请尝试将代码更改为:let promises=friendIDs.map(id=>fetchJSON(
/users/${id}
).concat(friend\u of friend\u id.map(id=>fetchJSON(
/users/${id}
))那样的话,你的两个要求都在你的承诺之内list@TomMendelson是的,你是对的,但我发现了一个更优雅的等待方式:
等待承诺。所有([p1,p2])
非常感谢!只需要一个捕获来处理错误,谢谢你的启发!实际上,为了替换reduce,我可以使用
(让friend\u id of friend\u of friend\u id){const response=wait fetchJSON(`users/${item}`);results.push(response)}
我认为它更干净。你认为呢?@SharonChai是的,那也很好,最后它也会这样做(别忘了合并两个数组)我在使用async await时遇到了另一个问题,你能帮忙吗?@AmerllicA可以告诉我为什么你发现它太长了,这样我就可以在其中添加免责声明;)