简体   繁体   English

Node.js:承诺在resolve()调用之前已解决?

[英]Node.js: Promise resolved before resolve() is called?

I'm very new to the world of Node.js and its asynchronous behaviors. 我对Node.js及其异步行为非常陌生。

I am trying to take a file, save a copy of it, append a line to the copied file and start using the copied file - in that sequence. 我正在尝试获取一个文件,保存它的副本,在复制的文件后追加一行,然后按顺序开始使用复制的文件。

This is roughly what I have right now... 这大致就是我现在所拥有的...

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);

The output shows 1 3 4 5 2 instead of 1 2 3 4 5. Can anyone share some lights on why "first" was able to resolve before "2" was printed? 输出显示的是1 3 4 5 2而不是1 2 3 45。谁能分享一些有关为什么在打印“ 2”之前“ first”能够解决的问题?

Thanks! 谢谢!

You're using promises incorrectly. 您使用的诺言不正确。 In your example, you are immediately invoking your promises. 在您的示例中,您立即调用了您的承诺。 Since their executor function (the callback with resolve / reject params) is called the moment a promise is instantiated, you're immediately logging 1,3,4, and 5. Since console.log('2') is wrapped in an async action's callback, it's being deferred and is ultimately being called last. 由于实例化承诺时会调用其执行程序功能(带有resolve / reject参数的回调),因此您将立即记录1,3,4和5。因为console.log('2')被包装在异步中动作的回调,它被推迟了,最终被称为last。

The correct way to implement what you're attempting is to set your variables to be functions themselves and return your promises instead. 实现您要尝试的操作的正确方法是将变量设置为函数本身,然后return您的promise。 This way, when your first , second , and third functions are called, they immediately invoke their executors and start the control flow. 这样,当您的firstsecondthird函数被调用时,它们立即调用其执行程序并开始控制流程。 It's imperative that you return the promises though, or you will break the promise chain. 您必须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);

Yields: 产量:

1
2
3
4
5

Here's a working version to play around with: 这是一个可以使用的工作版本:

 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); 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM