node.js中的回调和承诺之间有所不同

问题描述 投票:1回答:2

我的代码:

const readline = require('readline');

function scan(callback) {
    const rl = readline.createInterface({
        input: process.stdin,
        output: process.stdout,
        prompt: '> ',
    });

    rl.prompt();
    rl.on('line', (line) => {
        callback(line);
        rl.close();
    }).on('close', () => {
        process.exit(0);
    });
}

scan(data => {
    console.log('data: ', data);  // can console
});

我使用了回调,它可以控制你输入的数据,但是当我使用promise时它不会控制:

function scan() {
    return new Promise((resolve, reject) => {
        const rl = readline.createInterface({
            input: process.stdin,
            output: process.stdout,
            prompt: '> ',
        });

        rl.prompt();
        rl.on('line', (line) => {
            resolve(line);  
            rl.close();
        }).on('close', () => {
            process.exit(0);
        });
    });
}

scan().then(data => {
    console.log('data: ', data);   // can not console
});

发生了什么?回调和承诺之间有什么不同?

javascript node.js callback promise
2个回答
0
投票

堆栈和队列问题,您的回调与rl.close在同一堆栈上,但解析处理程序不在(队列中的那个)。

例如:

new Promise(resolve=>resolve())
.then(_=>console.log("last"))//resolve handler is going on queue
console.log("first")//this is on the same stack so logs
//nothing more on the stack so get stuff from queue

简单的解决方案是在解析处理程序后将关闭放在que上:

function scan() {
  return new Promise((resolve, reject) => {
      const rl = readline.createInterface({
          input: process.stdin,
          output: process.stdout,
          prompt: '> ',
      });

      rl.prompt();
      rl.on('line', (line) => {
          resolve(line);  
          //put close on queue
          Promise.resolve()
          .then(
            _=>rl.close()
          );
      }).on('close', () => {
          process.exit(0);
      });
  });
}

scan().then(data => {
  console.log('data: ', data);   // can not console
});

堆栈和队列videoducumentation


0
投票

有关更详细的答案,请参阅HMR的回复。

显然你在解决了诺言后立即调用了rl.close()。看看你的on close事件处理程序:

 process.exit(0);

显然,它将停止所有执行并终止您的程序。事件虽然您的承诺得到解决,但是更快地调用exit(事件循环的正常行为)。

所以要解决你的问题:删除on close事件处理程序。在每个承诺得到解决后,您的程序将优雅地终止。

© www.soinside.com 2019 - 2024. All rights reserved.