[英]Call a function inside a function in nodeJS
我正在使用 nodeJS 和 mongoDB。
我編寫了一個函數來獲取數據庫中最大的索引,以便在我在數據庫中發布新元素時能夠使用它。
我創建了一個函數來在我的數據庫中插入一個元素:
function postComparison(){
console.log("Titre : " + document.getElementById("Titre").value);
var myHeaders = new Headers();
myHeaders.append("Content-Type", "application/json");
var raw = JSON.stringify({
"_id": getLastIndice()+1, // HERE
"id_User": "2",
"PseudoUser": "bob",
"Titre" : document.getElementById("Titre").value
});
var requestOptions = {
method: 'POST',
headers: myHeaders,
body: raw,
redirect: 'follow'
};
fetch("http://localhost:3000/comparaison", requestOptions)
.then(response => response.text())
.then(result => console.log(result))
.catch(error => console.log('error', error));}
</script>
我正在調用getLastIndice()
函數來增加我在數據庫中的最后一個索引的索引。
函數getLastIndice()
調用路由器:
function getLastIndice(){
console.log("on appel la fonction get LastIndice");
var requestOptions = {
method: 'GET',
redirect: 'follow'
};
fetch("http://localhost:3000/comparaison/getLastIndice", requestOptions)
.then(response => response.text())
//.then(result => document.getElementById("textRepBDD").innerHTML = result)
.catch(error => console.log('error', error));
console.log('appel de la fonction qui recupere le dernier indice avec comme réponse : ' + response );
return parseInt(response);
}
</script>
在路由器內部我有:
comparaisonRouter.route('/getLastIndice')
.get( (req, res, next) => {
var MongoClient = require('mongodb').MongoClient;
var url = "mongodb://localhost:27017/";
MongoClient.connect(url, function(err, db) {
if (err) throw err;
var dbo = db.db("siteComparaisonMax");
//Sort the result by name:
var sort = { _id: -1 }; // - 1 Pour trier dans un ordre decroissant.
dbo.collection("comparaisons").find().sort(sort).limit(1).toArray(function(err, result) {
if (err) throw err;
//console.log(JSON.parse(result._id));
console.log(result[0]._id);
res.json(result[0]._id);
db.close();
});
});
})
函數 get last index 正在工作,但是當我調用postComparaison()
函數時,它只是調用了getLastIndice()
,僅此postComparaison()
。
我想我在某個地方錯過了 next() 。
要從承諾中返回一個值,您可以使用.then()
。 .then()
方法不是用來記錄結果的。 postComparaison()
可以調用以獲取結果:
function getLastIndice(){
console.log("on appel la fonction get LastIndice");
var requestOptions = {
method: 'GET',
redirect: 'follow'
};
// IMPORTANT! The `return` below in front of the `fetch()` is
// what will return the value to the caller:
return fetch("http://localhost:3000/comparaison/getLastIndice", requestOptions)
.then(response => response.text())
.then(result => {
console.log('code INSIDE THIS THEN executes AFTER we get response : ' + result );
return parseInt(result);
})
.catch(error => console.log('error', error));
console.log('code OUTSIDE THE THEN ABOVE executes BEFORE we get response');
}
這是非常重要的。 函數底部的代碼執行FIRST 。 然后執行LAST 中的代碼。
為了澄清,讓我們從函數中刪除所有細節:
function getLastIndice() {
// THIS HAPPENS FIRST
console.log('first');
return fetch()
.then(response => response.text())
.then(result => {
// THIS HAPPENS THIRD
console.log('third');
return parseInt(result);
});
// THIS HAPPENS SECOND
console.log('second');
}
上面的代碼會記錄:
第一第二第三
但請注意:
function getLastIndice() {
return fetch() // THIS RETURN IS IMPORTANT ! !
.then(r => r.json())
.then(r => parseInt(r));
}
所以基本上一個干凈版本的getLastIndice()
可以簡單地寫成:
function getLastIndice() {
var requestOptions = {
method: 'GET',
redirect: 'follow'
};
return fetch("http://localhost:3000/comparaison/getLastIndice", requestOptions)
.then(x => x.text())
.then(y => parseInt(y));
}
這就是所有需要的功能。 我們真的不需要(或不想)在這里捕獲錯誤,因為我們希望調用者能夠檢測到錯誤,因此我們只需刪除.catch()
。
現在該函數可以正常工作,下面是您在postComparison()
使用它的postComparison()
:
function postComparison() {
var myHeaders = new Headers();
myHeaders.append("Content-Type", "application/json");
// Remember, .then() is how getLastIndice() RETURNS its value:
getLastIndice().then(indice => {
var raw = JSON.stringify({
"_id": indice+1, // WE GOT THIS FROM .then of getLastIndice()
"id_User": "2",
"PseudoUser": "bob",
"Titre" : document.getElementById("Titre").value
});
var requestOptions = {
method: 'POST',
headers: myHeaders,
body: raw,
redirect: 'follow'
};
fetch("http://localhost:3000/comparaison", requestOptions)
.then(response => response.text())
.then(result => console.log(result))
.catch(error => console.log('error', error));
}
}
或者,您可以返回變量raw
並在另一個.then()
處理其余部分。 這就是 Promise 被發明的全部原因——通過鏈接.then()s
來扁平化回調嵌套:
function postComparison() {
var myHeaders = new Headers();
myHeaders.append("Content-Type", "application/json");
// Remember, .then() is how getLastIndice() RETURNS its value:
getLastIndice()
.then(indice => {
var raw = JSON.stringify({
"_id": indice+1,
"id_User": "2",
"PseudoUser": "bob",
"Titre" : document.getElementById("Titre").value
});
return raw; // return this to the `then` below:
})
.then(requestBody =>
var requestOptions = {
method: 'POST',
headers: myHeaders,
body: requestBody, // requestBody comes from raw above
redirect: 'follow'
};
return fetch("http://localhost:3000/comparaison", requestOptions);
})
.then(response => response.text())
.then(result => console.log(result))
.catch(error => console.log('error', error));
// ^^ NOTE: all the then() are on the same level!
}
如果你想postComparison()
返回的最終結果只是做我們一起做的同樣的事情getLastIndice()
以上:添加return
關鍵字前面getLastIndice()
function postComparison() {
var myHeaders = new Headers();
myHeaders.append("Content-Type", "application/json");
return getLastIndice() // THIS RETURN IS IMPORTANT !
.then(indice => {
var raw = JSON.stringify({
"_id": indice+1,
"id_User": "2",
"PseudoUser": "bob",
"Titre" : document.getElementById("Titre").value
});
return raw;
})
.then(requestBody =>
var requestOptions = {
method: 'POST',
headers: myHeaders,
body: requestBody, // requestBody comes from raw above
redirect: 'follow'
};
return fetch("http://localhost:3000/comparaison", requestOptions);
})
.then(response => response.text())
.then(result => {
console.log(result);
return result; // return the result into the chain of then()
// this return is ALSO IMPORTANT
})
.catch(error => console.log('error', error));
}
使用 Promise 時,您必須始終記住then()
中的代碼發生在函數結束之后,而不是之前! 如果你仔細想想,這實際上是有道理的。
例如,假設您要訂購比薩。 通常發生的事情是這樣的:
Restaurant()
並訂購比薩餅pizzaDeliveryGuy(() => will send you the pizza)
pizzaDeliveryGuy()
注意,在上述事件pizzaDeliveryGuy()
是.then()
和Restaurant()
使得Prmoise
送你一個比薩餅(使用pizzaDeliveryGuy()
盡管Restaurant()
答應你提供比薩餅,然后才放下手機send you the pizza
事件發生后,你放下了電話。
您的困惑正是這樣:不了解未來會發生承諾。 即使餐廳在您放下電話之前向您承諾了披薩,披薩送貨員也會在您下訂單后將披薩發送給您。 類似地, Promise
將在函數結束之后而不是之前執行.then()
回調。
ECMAScript 版本 6 引入了兩個有助於簡化async
代碼處理的關鍵字: async
和await
。 它們建立在Promise
之上,基本上是用於內聯Promise
的特殊語法。
基本上,如果你寫這樣的東西:
async function x () {
let y = await z();
console.log(y);
}
Javascript 會將它編譯成這樣:
function x () {
z().then(y => console.log(y));
}
使用async/await
我們可以簡化您的代碼。 首先,我們可以像這樣重寫getLastIndice()
:
async function getLastIndice() {
var requestOptions = {
method: 'GET',
redirect: 'follow'
};
let response = await fetch("http://localhost:3000/comparaison/getLastIndice", requestOptions);
let txt = await response.text();
return parseInt(txt);
}
因為我們使用await
上面函數中的所有內容都是從上到下依次發生的:
async function getLastIndice() {
// THIS HAPPENS FIRST
var requestOptions = {
method: 'GET',
redirect: 'follow'
};
// THIS HAPPENS SECOND
let response = await fetch(URL, requestOptions);
// THIS HAPPENS THIRD
let txt = await response.text();
// THIS HAPPENS LAST
return parseInt(txt);
}
現在我們可以像這樣重寫postComparison()
:
async function postComparison() {
var myHeaders = new Headers();
myHeaders.append("Content-Type", "application/json");
try {
let indice = await getLastIndice();
var raw = JSON.stringify({
"_id": indice+1,
"id_User": "2",
"PseudoUser": "bob",
"Titre" : document.getElementById("Titre").value
});
var requestOptions = {
method: 'POST',
headers: myHeaders,
body: raw
redirect: 'follow'
};
let response = await fetch("http://localhost:3000/comparaison", requestOptions);
let result = await response.text())
console.log(result);
return result;
}
catch(error) {
console.log('error', error);
}
}
如您所見,對於像這樣的簡單順序代碼, async/await
更容易閱讀。 只是不要忘記await
結果。
盡管如此,即使您使用async/await
我認為了解 Promises 的工作方式以及.then()
工作方式至關重要,因為async/await
是建立在.then()
之上的。 在某些情況下,您希望兩個或多個事物並行運行而不是順序運行,這就是您需要回到承諾和回調的時候。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.