簡體   English   中英

forEach循環中的XMLHTTPRequest不起作用

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM