2016-05-10 109 views
0

非常新的NodeJS,我試圖使用承諾提示用戶輸入按特定的順序。這裏是我的代碼:Node.js:多個然後沒有以正確的順序執行

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(),但不是這樣。謝謝你的幫助!我也樂意聽取關於如何清理代碼的建議。

回答

0

我不會說是承諾要做到這一點的方式,但如果你仍然想使用它,你誤會了如何使用他們手頭的任務。

每個異步代碼塊應該返回一個承諾,在你的情況下,這些將是在等待用戶輸入時的阻塞。

您可以定義返回新承諾或現有承諾並將它們鏈接到彼此的函數,從而能夠控制代碼的執行順序。

看看下面的簡單小提琴。請注意,getName返回一個新的承諾,該承諾使用Promise構造函數構造,該構造函數以執行器爲參數,提供承諾實現的resolvereject函數。

當您的異步代碼完成時,或者在這種情況下,阻止代碼,您只需解決具有或不具有解析值的承諾。

默認情況下,.then()函數返回一個新的承諾,並且如果返回.then()函數中的對象,它將自動解析,除非該對象是新承諾。

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文檔。

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

+0

但是,當我這樣做時,displayPlayers()在getType()有機會運行之前執行,導致未定義的輸出。 – cbrauns

1

,你不能依賴於then以特定的順序來執行代碼,then是一個異步函數。 如果您希望按照特定順序執行一系列承諾,請查看Async.js。它會是這樣的:

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

好吧,我肯定會的,但是我認爲那時候的整個要點是等到先前的那個完成,然後再執行下一個。 – cbrauns

+0

想當時同時運行多個線程,當然你可以開始先去哪個線程,但其他線程不必等待對方開始執行 –