2016-09-19 4 views
3

내 사용자 컨트롤러 내에 인덱스 동작이 있습니다. 두 가지 작업을 연속으로 수행하려고하는데 원하는 작업을 실행하지 않습니다. res.json() 메서드를 사용하여 둘 다 완료 할 수 있도록합니다.Promise - Promise 및 Bluebird Promise.each, Promise.map, Promise.all 등을 연결합니다.

사용자를 참여시키는 우정 조인 모델이 있습니다. 한 열은 frienderId이고 한 열은 friendedId입니다. 아래의 인덱스 함수에서 원하는 결과는 친구 인 단일 사용자 객체로 끝나게된다는 것입니다. 아래에 약속해야하는 이유는 사용자가 frienderId 열 또는 friendedId 열에있을 수 있기 때문입니다. 따라서 req.user의 친구에 대한 두 가지 상황을 본질적으로 파싱해야합니다.

마지막으로 반환되는 문제는 I.E. res.json (result)는 항상 올바른 친구를 반환하지만 원하는 객체보다 먼저 또는 그 다음에 빈 배열 []을 반환합니다. 이 빈 배열은 결과가없는 두 가지 약속 시나리오 중 하나에서 비롯됩니다. sayyy..reject와 같은 해결 대신에 어떤 유형의 메소드가 있습니까? 그곳에서 전화를 걸면 약속 전체가 약속의 집으로 밀려 들지 않을 것입니까? 그렇다면 나는 단지 (if friended) {reject} 또는 if (! friender) {reject}

각각의 약속을 통해 열거하고 각각의 결과를 제공한다는 것을 이해합니다. 그러나, 나는 각 약속의 결과를 원하지 않는다, 나는 단지 각 약속 실행의 부작용에 접근하고 싶다.

감사합니다.

index: function(req, res) { 
    var promiseArray = []; 

    promiseArray.push(new Promise(function(resolve) { 
     user.findById(req.user.id).then(function(user) { 
     user.getFrienders({ 
      where: { 
      username: req.body.username 
      } 
     }).then(function(friender) { 
      resolve(friender[0]) 
     }) 
     }) 
    })); 

    promiseArray.push(new Promise(function(resolve) { 
     user.findById(req.user.id).then(function(user) { 
     user.getFriendeds({ 
      where: { 
      username: req.body.username 
      } 
     }).then(function(friended) { 
      resolve(friended[0]) 
     }) 
     }) 
    })); 

    Sequelize.Promise.map(promiseArray, function(result) { 
     res.json(result); 
    }); 
} 
+0

또 다른 이상한 점은 바로 하단의 res.json (결과) 대신에 var promiseArray의 맨 아래에 var friend, 그 다음 console.log (friend)라는 정의되지 않은 변수를 추가하는 것입니다. 첫 번째는 정의되지 않았고, 두 번째는 올바른 친구 객체이고, 그 반대의 경우는 사용자가 존재하는 열 (frienderId 또는 friendedId)에 따라 다릅니다. 콘솔에서 하나의 변수를 로깅 할 때 두 개의 완전히 다른 값이 기록 될 수 있다는 점에서 매우 혼란 스럽습니다. 고마워. –

+0

안녕하세요 형제 님, 좀 더 명확한 내용이 필요하면 내 게시물에 대한 후속 질문을 할 수 있으면 좋을 것입니다. 그렇지 않으면 내 대답이 도움을 준 경우 동의합니다. –

답변

2

우선 Promise의 사용은 약간 중복됩니다. findById() 함수가 약속을 반환하기 때문에 처리해야합니다. new Promise을 만들 필요가 없습니다. promiseArray.push(user.findById ...)이라고 말할 수 있습니다. 거의 then을 올바르게 사용하고 있습니다. then에 전달 된 함수는 약속이 해결되었을 때 호출됩니다.이 경우 findById 함수가 완료되고 값을 반환 한 후 호출됩니다. then 자체는 콜백이 반환하는 값으로 해결되는 약속을 반환합니다. 따라서 promiseArray에서 모든 작업을 끝내기를 원하는 값이 무엇이든간에 friended[0] 또는 friender[0]이라고 가정하면 마지막 then 함수에서 값을 반환하면됩니다. 첫 번째 then 함수 내부, 당신은 또한 return user.findFriends(...

는 당신이 다음에해야 할 것은 약속이 거부 된 findById 기능에서 반환되는 경우를 처리라고한다. 당신은 두 가지 방법으로 그렇게 할 수 있습니다. 먼저 약속이 거절 된 경우에 호출 될 두 번째 콜백을 then에 전달할 수 있습니다.이 경우 거부 이유가 인수로 사용됩니다. 두 개의 함수를 then에 전달하는 대신 thencatch으로 따라갈 수 있습니다. 이는 내가 개인적으로 선호하는 것이며, 거부 콜백을 catch으로 전달합니다. catch은 콜백에서 반환 된 값으로 해결되는 약속을 반환합니다. 전달 된 이유 또는 원하는 값을 반환하도록 선택할 수 있습니다. 따라서 오류가 거부 된 경우 catch이 반환하는 것이 무엇이든지 약속 배열에 저장됩니다.

약속을 위해 the documentation을 읽는 것이 좋습니다. 시피, 내가 처음 시작했을 때 나는 약속에 어려움을 겪었습니다.하지만 문서를 읽고 예제를 연습 한 후에는 손을 잡고 유용한 약속이 무엇인지 확인하십시오.그것은 나를라면

이 내가 당신은 다른 모든 동일하게 유지 할 수있는 코드를

var frienderPromise = user.findById(req.user.id) 
      .then(function(user) { 
      return user.getFrienders({ 
       where: { username: req.body.username } 
      }); 
      }) 
      .then(function (friender) { 
      return friender[0]; 
      }) 
      .catch(function (reason) { 
      return reason; // or whatever else you want to end up in the promisesArray on rejection 
      }); 

    var friendedPromise = user.findById(req.user.id) 
      .then(function(user) { 
      return user.getFriendeds({ 
       where: { username: req.body.username } 
      }); 
      }) 
      .then(function (friended) { 
      return friended[0]; 
      }) 
      .catch(function (reason) { 
      return reason; 
      }); 

    promiseArray.push(frienderPromise); 
    promiseArray.push(friendedPromise); 

리팩토링 것이 방법이다. 결국 현재와 마찬가지로 Sequalize으로 전화 할 수 있습니다. 비록 그것은 return Sequalize...이어야합니다. 나쁜 결과를 유지하지 않으려면 .map 대신 Promise.filter을 사용하는 것도 좋습니다. 그래서 당신은 개인적으로

return Sequelize.Promise.filter(promiseArray, function(result) { 
     if (/* make sure it's result you want */) 
     res.json(result); 
    }); 

같은 것을 할 수있는, 나는 한 단계 더 가서 res으로 아무것도하지 않고 한 번 그런

return Sequelize.Promise.filter(promiseArray, function(result) { 
     return result === /* result you want */; 
    }); 

으로 마무리 다른 함수에 약속 사업을 모두 제거 할 당신의 index 함수 내에서, 당신은

return friendsPromiseFunction().then(function (results) { 
     res.json(results); 
    }) 

그것은 일을 많이 청소기 만들 것 부를 수 있었다. 희망이 도움이됩니다. 질문이 있으면 알려주세요.

+0

나는 블루 버드 약속 (Bluebird Promise) 방법을 사용하지 않고 대신 정기적 인 후속 약속 체인을 사용했다. 이 과정은 나를위한 실험이었고 나는 FRIENDED에 대한 질의를 할 수 있다는 것을 깨닫지 못했다. 그런 다음 간단히 .then 호출을 사용하고 FRIENDER에 대해 동일한 질의를 수행했다. 나는 그 다음에 FRIENDED와 FRIENDER 모두를 반환 값으로 사용하여 약속의 사슬 아래에서 아무런 문제없이 질의를 할 수있었습니다. 도와 주셔서 감사합니다! Upvoted. –