2016-08-18 80 views
0

我已經開始玩Node.js了,但是我在異步功能方面遇到了問題,我可以製作一款遊戲小遊戲。但我能夠使異步函數與同步函數一起工作的唯一方法是使用全局變量。將異步函數與同步函數混合?

var promptly = require("./promptly"); //needed for input {npm install promptly} 
var firstName; 
var lastName; 

GetFirstName(); 

function GetFirstName() { //asynchronous function 
    promptly.prompt('You first name: ', function (err,value) { 
     firstName = value; 
     getLastName(); 
    }); 
} 

function getLastName() { //asynchronous function 
    promptly.prompt('You last name: ', function (err,value) { 
     lastName = value; 
     printName(); 
    }); 
} 

function printName() { //synchronous function 
    console.log(firstName+" "+lastName); 
} 

這工作,但我有5異步功能的小遊戲與全球14個變量結束。所以我的問題是做這樣的事情的正確方法是什麼?

+3

應該有零全局變量。你知道將參數傳遞給函數嗎?這就是你如何將信息從一個上下文傳遞到另一個函數而不使用全局變量。這是一個非常基本的編程概念,所以它可能對您遵循一些關於編程基礎知識的在線教程非常有幫助,而不僅僅是在沒有經過適當培訓的情況下編寫代碼。 – jfriend00

+1

在promises上教育自己,這是使用異步函數的正確方法,就像它們是同步的。檢查f.i.這個關於承諾點的鏈接:https://gist.github.com/domenic/3889970。在異步函數的回調中混淆調用異步函數會導致回調地獄,並且它不是製作通用,可測試和可重用代碼的可靠方法。編輯:實際上@Brandon答案得到的點 – Sergeon

+0

我知道應該有零全局變量我知道關於傳遞函數的參數。問題是我有很多函數會得到一個變量,需要轉到函數的第五個函數,必須有一個更好的方法,而不是將這個變量傳遞給4個函數,永遠不會使用它。 – Ashlin

回答

1

什麼@ jfriend00指的是在他/她的評論是,當你定義一個函數,你可以定義parameters該功能應該採取。記住

有了這一點,你可以重寫你的代碼是這樣的:

var promptly = require("./promptly"); //needed for input {npm install promptly} 


GetFirstName(); 

function GetFirstName() { //asynchronous function 
    promptly.prompt('You first name: ', function (err,firstName) { 

     getLastName(firstName); 
    }); 
} 

function getLastName(firstName) { //asynchronous function 
    promptly.prompt('You last name: ', function (err,lastName) { 

     printName(firstName, lastName); 
    }); 
} 

function printName(firstName, lastName) { //synchronous function 
    console.log(firstName+" "+lastName); 
} 

注意,每個進程的「一步」接受來自之前的「一步」的結果。

你使用被親切地稱爲callback hell異步技術,爲callback S(即functions你傳遞給.prompt()作爲第二個參數)往往巢深深&很快變得難以管理。

JavaScript這幾天有很多解決方案來解決這個問題。一旦你瞭解了異步程序的「流程」,我建議尋找一些更加用戶友好的選項(以我們的鹽片爲例,它們只是爲了說明概念):

async.js - 這個圖書館有很多很好的工具可以幫助你寫的回調更可讀的方式:

async.series([ 
    asyncFunction1(arg, callback) { 
    // code 
    callback() 
    }, 
    asyncFunction2(arg, callback) { 
    // code 
    callback() 
    }, 
    asyncFunction3(arg, callback) { 
    // code 
    callback() 
    } 
] 

Promises - 在Javascript中的新功能和一個圖書館已經支持。引擎蓋下這些都是有趣的,但實際上他們只是允許更清晰的代碼和錯誤處理:

asyncFunction1(args) { 
    // code 
    return x 
} 
.then(asyncFunction2(x) { 
    // code 
    return y 
}) 
.then(asyncFunction3(y) { 
    // code 
    return z 
}) 

async/await - 最新嘗試之一是解決異步代碼的挑戰。我個人還沒有使用過它們,但是這些例子很有趣。

async function getName() { 
    let firstName = await getFirstName() 
    let lastName = await getLastName() 
    console.log("Your name is " + firstName + lastName) 
} 

我鏈接的最後一篇文章絕對值得一讀,以便對異步挑戰有一個很好的概述。這不是一個簡單的概念,但一旦點擊,它就非常直觀。

+0

FWIW這不是回調地獄。這是回調地獄的解決方案:分別定義函數而不是嵌套。 – slebetman

0

通行證firstNamegetLastName()再通firstNamelastNameprintName()。下面是一些示例代碼:

var promptly = require("promptly"); 
GetFirstName(); 

function GetFirstName() { 
    promptly.prompt('You first name: ', function (err,value) { 
    getLastName(value); 
    }); 
} 

function getLastName(firstName) { 
    promptly.prompt('You last name: ', function (err,value) { 
    printName(firstName, value); 
    }); 
} 

function printName(firstName, lastName) { 
    console.log(firstName + " " + lastName); 
}