Node.js:多个然后没有以正确的顺序执行

时间:2016-05-10 13:15:20

标签: javascript node.js promise

非常是NodeJS的新手,我正在尝试使用promises来提示用户按特定顺序输入。这是我的代码:

var prompt = require('prompt');
var promising = require("promise-adapter");

var promptGet = promising(prompt.get);

prompt.start();

function Game () {
    playerOneName = '';
    playerTwoName = '';
    pOneType = true; 
}

//prompts the user for two names and assigns them 
//to player one and player to for the game object
Game.prototype.getName = function (resolve){
    promptGet(['playerName1', 'playerName2']).then(function(result){
        this.playerOneName = result.playerName1;
        this.playerTwoName = result.playerName2;
    })
    .then(function() {
        resolve();
    });
}

Game.prototype.getType = function (resolve) {
    //console.log('made it to the function');
    promptGet(['Player1Type']).then(function(result){
        if (result.Player1Type !== "X"){ this.pOneType = false;}
        //console.log(this.pOneType);
    })
    .then(function(){
        resolve();
    });
}
Game.prototype.displayPlayers = function(resolve) {
    if (pOneType === true){
        console.log(this.playerOneName + " will be X's");
        console.log(this.playerTwoName + " will be O's");
    }
    else {
        console.log(this.playerOneName + " will be O's");
        console.log(this.playerTwoName + " will be X's");
    } 
    console.log("Let's Get Started!");
}

var test = new Game();

new Promise(function(resolve, reject){
        test.getName(resolve);
    })
    .then(function(resolve, reject){
        test.getType();
    })
    .then(function(resolve, reject){
        test.displayPlayers();
    });

我知道这是非常草率的代码,但即便如此,我认为它应该工作,以便test.displayPlayers()在 test.getType()之前执行,但事实并非如此。谢谢你的帮助!我也愿意听取有关如何清理代码的建议。

3 个答案:

答案 0 :(得分:1)

您不能依赖then按特定顺序执行代码,then是一个异步函数。 如果您希望以特定顺序执行一系列承诺,请查看Async.js。它会是这样的:

async.series([
    function(){ ... },
    function(){ ... }
]); 

答案 1 :(得分:0)

我没有看到你的问题,对我来说,承诺像活动一样。

如果你真的想在test.getType()之后执行test.displayPlayers();做那样的事情:

var prompt = require('prompt');
var promising = require("promise-adapter");

var promptGet = promising(prompt.get);

prompt.start();

function Game () {
    playerOneName = '';
    playerTwoName = '';
    pOneType = true; 
}

//prompts the user for two names and assigns them 
//to player one and player to for the game object
Game.prototype.getName = function (resolve){
    promptGet(['playerName1', 'playerName2']).then(function(result){
        this.playerOneName = result.playerName1;
        this.playerTwoName = result.playerName2;
    })
    .then(function() {
        resolve();
    });
}

Game.prototype.getType = function (resolve) {
    //console.log('made it to the function');
    promptGet(['Player1Type']).then(function(result){
        if (result.Player1Type !== "X"){ this.pOneType = false;}
        //console.log(this.pOneType);
    })
    .then(function(){
        resolve();
    });
}
Game.prototype.displayPlayers = function(resolve) {
    if (pOneType === true){
        console.log(this.playerOneName + " will be X's");
        console.log(this.playerTwoName + " will be O's");
    }
    else {
        console.log(this.playerOneName + " will be O's");
        console.log(this.playerTwoName + " will be X's");
    } 
    console.log("Let's Get Started!");
}

var test = new Game();

new Promise(function(resolve, reject){
        test.getName(resolve);
    })
    .then(function(resolve, reject){
        test.getType();
        test.displayPlayers();
    })

答案 2 :(得分:0)

我不会说承诺是这样做的方式,但是如果你仍然想要使用它,你就会误解如何将它们用于手头的任务。

每个异步代码块都应该返回一个promise,在你的情况下,那些在等待用户输入时会被阻塞。

定义返回新promise或现有promise的函数,并将它们相互链接,从而能够控制代码的执行顺序。

看看下面的简单小提琴。请注意,getName返回一个新的promise,它使用Promise构造函数构造,该构造函数将执行程序作为参数,提供promise实现的resolvereject函数。

当您的异步代码完成时,或者在这种情况下是阻止代码时,您只需使用或不使用已解析的值来解析promise。

默认情况下,.then()函数返回一个新的promise,如果你在.then()函数中返回一个对象,它将被自动解析,除非该对象是一个新的promise。

function Game() {
  var playerOneName = '';
  var playerTwoName = '';
  var pOneType = true;
}

//prompts the user for two names and assigns them 
//to player one and player to for the game object
Game.prototype.getName = function(resolve) {
  return new Promise(function(resolve, reject) {
    var playerOneName = prompt("Please enter your name", "Harry Potter");
    var playerTwoName = prompt("Please enter your name", "Ron Weasley");
    if (playerOneName !== null && playerTwoName !== null) {
      resolve();
    } else {
      reject();
    }
  });
}

var someOtherFunction = function() {
  alert("This is inside some other function!");
  return "A value that gets resolved by the promise!";
}


var testGame = new Game();
testGame.getName()
  .then(function() {
    alert("This happens when names have been chosen!");
  })
  .then(someOtherFunction)
  .then(function(resolvedValue) {
    alert(resolvedValue);
  })

从这里你应该能够获得承诺的基本内容,但我强烈建议你阅读MDN Promise文档。