2016-07-15 2 views
1

약속이 예상대로 작동하는 데 문제가 있습니다. 다음 작업을 수행해야합니다.약속을 해결하기 전에 nodejs then() 함수가 실행됩니다.

표준 출력에서 ​​파일 이름을 가져 와서 줄로 나누어 복사합니다. 복사 작업이 끝나면 다른 작업을 시작하고 여기에 문제가 있습니다.

오류가 발생하면 Promise 내부에 복사 기능을 만들었습니다. 오류가 발생해도 루프가 완료된 후 오류가 해결되지 않으면 어떤 이유로 인해 then() 함수가 복사되기 전에 실행됩니다. 작업이 완료되었습니다

var lines = stdout.split(/\r?\n/); 

copyUpdatedFiles(lines).then(
    function() { 
     console.log('this one should be executed after copy operation'); 
    } 
); 

function copyUpdatedFiles(lines) { 
    return new Promise(function(resolve, reject) { 
     for (var i = 0; i < linesLength; i++) { 
      fs.copy(lines[i], target, function(err) { 
       if (err) { 
        reject(); 
       } 
      }); 
     } 
     resolve(); 
    }); 
} 

제가 분명히 뭔가를 잃어 버리게 도와주세요.

답변

3

는하지만 그들은을 완료 이전 사본을 시작한 후 당신이하고있는 한, 최대한 빨리 resolve 전화로 해결됩니다. resolve 전에 마지막 콜백을 기다려야합니다. 당신은 표준 사용할 수 있도록

function copyUpdatedFiles(lines) { 
    return new Promise(function(resolve, reject) { 
     var callbacks = 0;        // *** 
     for (var i = 0; i < linesLength; i++) { 
      fs.copy(lines[i], target, function(err) { 
       if (err) { 
        reject(); 
       } else {        // *** 
        if (++callbacks == lines.length) { // *** 
         resolve();      // *** 
        }         // *** 
       }          // *** 
      }); 
     } 
    }); 
} 

다른 방법을, 거기 라이브러리의 몇 가지 약속-쓸어 NodeJS 스타일의 콜백이 있습니다 : 그것은 당신이 *** 의견을 참조, 참조 얼마나 많은 추적하는 데 의미 Promise.all과 같은 약속 작곡 기법.

function copyUpdatedFiles(lines) { 
    return Promise.all(
     // CONCEPTUAL, semantics will depend on the promise wrapper lib 
     lines.map(line => thePromiseWrapper(fs.copy, line, target)) 
    ); 
} 

사이드 참고 : 귀하의 루프 조건 코드에서 아무 곳이나 정의되지 않은 변수 linesLength을 의미 당신이 그 중 하나를 사용한다면, 당신은 단지 뭔가이 작업을 수행 할 것입니다. lines.length이어야합니다.

+0

더 구체적으로 약속을 여러 번 거부하고 해결할 수 없으므로 해결할 경우 한 번 해결하고 거부 할 경우 거부 + 휴식 또는 다른 방법으로 해결할 수 있습니다. – atrifan

+0

@atrifan : 문제는 반복 된 호출이 아니라 너무 빨리 첫 번째 호출을하는 것입니다. 반복적으로 거부/해결 호출은 의미가 없지만 문제의 근본 원인은 아닙니다. –

0

for, 모두 fs.copy을 호출 스택에 넣었지만 약속을 완료하기 전에 복사가 성공할 때까지 기다리지는 않았지만 완료되지 않았습니다.

콜백 내부의 카운터를 fs.copy으로 사용하고 콜백이 호출 될 때마다 전화를 걸거나 async을 사용할 수 있습니다.

var async = require('async'); 
var lines = stdout.split(/\r?\n/); 

copyUpdatedFiles(lines).then(
    function() { 
     console.log('this one should be executed after copy operation'); 
    } 
); 

function copyUpdatedFiles(lines) { 
    return new Promise(function(resolve, reject) { 
     async.map(lines, (line, callback) => { 
      fs.copy(line, target, (err) => { 
       callback(err); 
      }); 
     }, 
     (err) => { 
      if(err) { 
       reject(); 
      } else { 
       resolve(); 
      } 
     }); 
    }); 
} 
관련 문제