2016-07-09 6 views
1

Ich bin sehr neu in der Welt von Node.js und seine asynchronen Verhaltensweisen.Node.js: Das Versprechen wurde aufgelöst, bevor der Aufruf von resolve() erfolgt?

Ich versuche eine Datei zu nehmen, eine Kopie davon zu speichern, eine Zeile an die kopierte Datei anzuhängen und die kopierte Datei zu verwenden - in dieser Reihenfolge.

Die grob, was ich jetzt habe ...

var first = new Promise(function(resolve, reject) { 
    console.log("1"); 
    var readStream = fs.createReadStream("file.txt"); 
    var writeStream = fs.createWriteStream("file-copy.txt"); 
    readStream.on("end", function() { 
     writeStream.end(); 
    }); 

    var pipeAction = readStream.pipe(writeStream); 
    pipeAction.on("close", function() { 
     console.log("2"); 
     resolve(); 
    }); 
}); 

var second = new Promise(function(resolve, reject) { 
    console.log("3"); 
    fs.appendFile("file-copy.txt", "\nA NEW LINE TO INSERT", function (err) { 

    }); 
    console.log("4"); 
    resolve(); 
}); 

var third = new Promise(function(resolve, reject) { 
    // do something with the modified, copied file 
    console.log("5"); 
}); 

first.then(second).then(third); 

Die Ausgabe zeigt 1 3 4 5 2 statt 1 2 3 4 5. Kann einige Lichter jemand auf teilen, warum "ersten" war in der Lage auflösen, bevor "2" gedruckt wurde?

Danke!

+1

Die Funktion wird sofort ausgeführt, wenn das Versprechen erstellt. –

+0

Macht Sinn, danke! – S200

Antwort

4

Sie verwenden promises falsch. In Ihrem Beispiel rufen Sie sofort Ihre Versprechen auf. Da ihre Executor-Funktion (der Callback mit resolve/reject params) den Moment aufgerufen wird, in dem ein Versprechen instanziiert wird, protokollieren Sie sofort 1,3,4 und 5. Da console.log('2') in den Callback einer asynchronen Aktion eingeschlossen ist, wird sie verzögert und wird zuletzt zuletzt genannt.

Die richtige Art und Weise zu implementieren, was Sie versuchen, ist Ihre Variablen zu setzen, um Funktionen selbst und return Ihre Versprechen statt. Auf diese Weise rufen die Funktionen first, second und third sofort ihre Executoren auf und starten den Steuerungsfluss. Es ist zwingend notwendig, dass Sie die Versprechen, aber, oder Sie werden die Versprechen-Kette zu brechen return.

function first() { 
    return new Promise(function(resolve, reject) { 
    console.log("1"); 
    var readStream = fs.createReadStream("file.txt"); 
    var writeStream = fs.createWriteStream("file-copy.txt"); 
    readStream.on("end", function() { 
     writeStream.end(); 
    }); 

    var pipeAction = readStream.pipe(writeStream); 
    pipeAction.on("close", function() { 
     console.log("2"); 
     resolve(); 
    }); 
    }); 
} 

function second() { 
    return new Promise(function(resolve, reject) { 
    console.log("3"); 
    fs.appendFile("file-copy.txt", "\nA NEW LINE TO INSERT", function(err) { 

    }); 
    console.log("4"); 
    resolve(); 
    }); 
} 

function third() { 
    return new Promise(function(resolve, reject) { 
    // do something with the modified, copied file 
    console.log("5"); 
    }); 
} 

first().then(second).then(third); 

Ausbeuten:

1 
2 
3 
4 
5 

Hier ist eine funktionierende Version zu spielen, um:

in einem Versprechen Konstruktor

function first() { 
 
    return new Promise((resolve, reject) => { 
 
    console.log(1); 
 
    // async request 
 
    setTimeout(() => { 
 
     console.log(2); 
 
     resolve(); 
 
    }, 1000); 
 
    }); 
 
} 
 

 
function second() { 
 
    return new Promise((resolve, reject) => { 
 
    console.log(3); 
 
    // async request 
 
    setTimeout(() => { 
 
     console.log(4); 
 
     resolve(); 
 
    }, 1000); 
 
    }); 
 
} 
 

 
function third() { 
 
    return new Promise((resolve, reject) => { 
 
    console.log(5); 
 

 
    resolve(); 
 
    }); 
 
} 
 

 
first() 
 
    .then(second) 
 
    .then(third);

+0

Fantastisch, das funktioniert! Danke und Will für die netten Tipps. – S200

+0

Sie sind herzlich willkommen. Asynchrone Programmierung kann schwer fassbar sein. – Seth

Verwandte Themen