2016-07-15 42 views
1

我有一個使Promise按預期工作的問題。我需要做的事情如下:nodejs然後()函數執行之前承諾解決

我從stdout中獲取文件名,將它們分成一行並複製它們。複製操作完成後,我想開始其他操作,這是我的問題。

我在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();      // *** 
        }         // *** 
       }          // *** 
      }); 
     } 
    }); 
} 

或者,有幾個庫,在那裏,承諾-IFY的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(); 
      } 
     }); 
    }); 
} 
相關問題