[英]XMLHTTPRequest inside forEach loop doesn't work
嗨,我正在編寫一個簡短的node.js應用程序,該應用程序每次在數組上進行迭代時都會向API發送XMLHTTPRequest。 問題是由於異步特性,它在返回請求之前會繼續執行foreach循環。 我可能忽略了一些大問題,但今天下午大部分時間都花在了我上面。 我試過使用await無濟於事,任何解決方案將不勝感激。
提前致謝。
NODE JS應用
const mongoose = require("mongoose");
const fs = require("fs");
const ajax = require("./modules/ajax.js");
// Bring in Models
let Dictionary = require("./models/dictionary.js");
//=============================
// MongoDB connection
//=============================
// Opens connection to database "test"
mongoose.connect("mongodb://localhost/bookCompanion");
let db = mongoose.connection;
// If database test encounters an error, output error to console.
db.on("error", (err)=>{
console.console.error("Database connection failed.");
});
// Check for connection to the database once.
db.once("open", ()=>{
console.info("Connected to MongoDB database...");
fs.readFile("./words.json", "utf8", (err, data)=>{
if(err){
console.log(err);
} else {
data = JSON.parse(data);
data.forEach((word, index)=>{
let search = ajax.get(`LINK TO API?=${word}`);
search.then((response)=>{
let newWord = new Dictionary ({
Word: response.word,
phonetic: response.phonetic,
meaning: response.meaning
}).save();
console.log(response);
}).catch((err)=>{
console.log(err);
});
});
}
});
});
XMLHTTPRequest模塊
// Get Request module utilising promises
const XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest;
const get = (url)=>{
// This function will return a promise, promises use resolve and reject. The resolve is accessed through .then and the reject through the .catch
return new Promise((resolve, reject)=>{
// Create new XMLhttp (AJAX) Request
let xhr = new XMLHttpRequest();
// Sets up the request, setting it to a GET request, pointing to the website and setting it to asynchronous
xhr.open("GET", url , true);
//sends the request
xhr.send();
xhr.onload = ()=>{
if (xhr.status == 200){
// When loaded pass the response over to the .then method
resolve(JSON.parse(xhr.responseText));
} else {
// if error pass the status code to the .catch method for error handling
reject(xhr.statusText);
}
};
xhr.onerror = ()=>{
// if error pass the status code to the .catch method for error handling
reject(xhr.statusText && xhr.status);
};
});
};
module.exports.get = get;
您應該使用promise.all等待所有的諾言完成。 Promise.all在輸入ans等待所有承諾都得到解決之前接受承諾的數組。 如果您使用promise.all,那么您的代碼將是這樣的。
const mongoose = require("mongoose");
const fs = require("fs");
const ajax = require("./modules/ajax.js");
// Bring in Models
let Dictionary = require("./models/dictionary.js");
//=============================
// MongoDB connection
//=============================
// Opens connection to database "test"
mongoose.connect("mongodb://localhost/bookCompanion");
let db = mongoose.connection;
// If database test encounters an error, output error to console.
db.on("error", (err) => {
console.console.error("Database connection failed.");
});
// Check for connection to the database once.
db.once("open", () => {
console.info("Connected to MongoDB database...");
fs.readFile("./words.json", "utf8", (err, data) => {
if (err) {
console.log(err);
} else {
data = JSON.parse(data);
var promiseArr = []
Promise.all(promiseArr.push(
new Promise((resolve, reject) => {
let search = ajax.get(`LINK TO API?=${word}`);
search.then((response) => {
let newWord = new Dictionary({
Word: response.word,
phonetic: response.phonetic,
meaning: response.meaning
}).save();
console.log(response);
resolve();
}).catch((err) => {
console.log(err);
reject();
});
})
)).then((response) => {
//whatever you want to do after completion of all the requests
})
}
});
});
當使用較小的數組時,我的代碼似乎運行良好,我真正遇到的問題是處理forEach循環和內存的阻塞性質。 我需要循環遍歷的數組超過40萬個單詞,並且應用程序在forEach循環可以完成並釋放調用堆棧以供httprequest解析之前耗盡內存。
非常感謝您提供有關如何創建不阻塞調用堆棧的同步forEach循環的任何信息。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.