2016-09-12 2 views
0

for 루프가 다음 루프로 진행될 때까지 기다리는 방법은 무엇입니까?노드 약속에 대한 결과 기다림

userdetails가 실행되고 realresult.playername이 전달되기 전에 새 변수에 할당되었는지 어떻게 확인할 수 있습니까?

코드 :

return new Promise(function (resolve, reject) { 

    arr = []; 


    messages.find({convid: convid}).then(function(result) { 

     for(var a in result) { 
      realresult = result[a]; 

      userData.userDetails(realresult.userid).then(function (result) { 
       realresult.playername = result.username; 
      }); 
      userData.usercashinfo(realresult.userid).then(function (resulttwo) { 
       realresult.playerdetails = resulttwo; 
      }); 

      arr.push(realresult); 

     } 

     return resolve(arr); 
    }); 
}); 
+0

사용'Promise.all' https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all –

+0

@Daniel_L 난 몰라 어떻게 작동하도록 내 기능을 리메이크 할 것입니다 – maria

+0

[Javascript for loop Promises]의 가능한 복제본 (http://stackoverflow.com/questions/32701957/javascript-for-loop-promises) – Roberrrt

답변

1

당신은 그것을 해결하면, 해결 약속 값의 배열을 반환, 약속을 쓰기 위해 노력하고 있습니다. 여기에서해야 할 2 가지가 있습니다 :

  1. 약속 완료를 기다리는 데는 return을 사용하십시오. promise chain에서, return ed가 아니라면 약속 값을 실제로 결정하는 것은 없습니다. (message.find()에 대해서도 이것을 사용해야합니다.
  2. 배열을 반복하는 것이 아니라 약속의 배열로 구성하여 약속을 해결할 때 배열로 푸시하도록합니다.
  3. Promise.all()을 사용하여 약속 개체를 수집합니다. all()은 전달 된 모든 약속이 해결 된 후에 만 ​​반환됩니다.
  4. (선택 사항) result 변수 이름을 여러 가지 의미로 다시 사용하지 마십시오. 여기서 잘못된 것은 아니지만 불필요한 혼란을 야기 할 수 있습니다.

이 같은 것을 볼 것, 함께 넣어 :

return messages.find(...).then(function(result) { 
    var promiseArr = []; 
    for (var a in result) { 
    promiseArr.push(
     promise.all([userData.userDetails(...), userData.usercashinfo(...)]) 
     .then(function(detailinfo) { 
     var realresult = result[a]; 
     var details = detailinfo[0]; 
     var cashinfo = detailinfo[1]; 
     realresult.playername = details.username; 
     realresult.playerdetails = cashinfo; 
     return realresult; 
    }); 
    } 
    return Promise.all(promiseArr); 
}); 
+0

안녕하세요. @yoz, 내 게시물을 업데이트했습니다. 수정 작업을 수행 할 수 있습니까? – maria

+0

@maria 확실히 여기 샘플 코드가 업데이트되었습니다. – yoz

0

그래서 나는 그것이 발전기와 약속의 조합으로 해결하려고하는 것이 좋습니다 생각을, 나는 확실하지 않다 그것의 가장 좋은 것을 가는 길,하지만 그 두 가지의 조합에 대한 좋은 연습 그래서 나는 그것을 시도했다.

아이디어는 생성기 함수가 새로운 반복을 시작하기 전에 콜백 함수를 기다리고 있으며 콜백 함수가 생성기 함수에 반복 실행을 알리기 전에 두 약속이 완료되기를 기다리는 것입니다.

here is a more simple example that I first tried on codepen

return new Promise(function (resolve, reject) { 
    arr = []; 
    messages.find({convid: convid}).then(function(result) { 
     function* iterations() { 
      for (var i = 0; i < result.length; i++) { 
       realresult = result[i]; 
       try { 
        var cbResult = yield cb(result[i].userid); 
        realresult.playername = cbResult.playername; 
        realresult.playerdetails = cbResult.playerdetails; 
        arr.push(realresult); 
       } catch (e) { reject(e) } 
      } 
      return arr.value; 
     } 

     var it = iterations(); 
     it.next(); 

     function cb(userid) { 
      Promise.all([ 
         userData.userDetails(userid), 
         userData.usercashinfo(userid) 
         ]).then(
          function(values) { 
           var realresult = {playername : values[0], playerdetails : values[1]} 
           returnValue = it.next(realresult); 
           if (returnValue.done) { 
            resolve(returnValue); 
           } 
          }, 
          function(e) { reject(e) } 
         ); 
     } 
    }); 
}); 
+1

['Promise' 생성자 반 패턴을 피하십시오] (http://stackoverflow.com/q/23803743/1048572)! – Bergi

+0

이 코드는 복잡하고 복잡한 오류는 처리하지 않습니다. 생성기를 사용하는 대신'async' /'await'를 사용해야합니다. – Bergi

+0

http://prntscr.com/ch6i49 나는 당신이 @naortor에서 한 일을했지만 보통의 응답으로 배열을 반환하지 않을 것입니까? [0]과 [1] 같이? – maria

관련 문제