2016-07-15 71 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(); 
      } 
     }); 
    }); 
} 
相关问题