Javascript 使用多个嵌套函数和for循环处理回调?

Javascript 使用多个嵌套函数和for循环处理回调?,javascript,Javascript,我学习javascript语法大约一周了,对整个异步-同步情况一无所知。我创建了一个函数,该函数可以从页面中刮取名称,将这些名称添加到清单数组中,逐个搜索清单中的每个名称,然后刮取结果页面中找到的名称,依此类推,直到找不到更多的名称。有点像微型网络爬虫 无论如何,这一背景与问题无关。我的目标是在txt文件中执行所有函数和for循环之后添加结果数组。我这样做只是为了让调试过程更容易管理,这样以后发生的事情就不重要了。我只是想了解如何以模仿同步处理的方式执行这些函数。我已经研究了回调、异步/等待函数

我学习javascript语法大约一周了,对整个异步-同步情况一无所知。我创建了一个函数,该函数可以从页面中刮取名称,将这些名称添加到清单数组中,逐个搜索清单中的每个名称,然后刮取结果页面中找到的名称,依此类推,直到找不到更多的名称。有点像微型网络爬虫

无论如何,这一背景与问题无关。我的目标是在txt文件中执行所有函数和for循环之后添加结果数组。我这样做只是为了让调试过程更容易管理,这样以后发生的事情就不重要了。我只是想了解如何以模仿同步处理的方式执行这些函数。我已经研究了回调、异步/等待函数以及在这个脚本中成功实现它们的承诺。我有很多嵌套函数和for循环,所以我猜我遇到了范围问题

这个脚本是一个我实际上正在刮的东西的模型。然而,实际的脚本是相同的,只是更改了被刮取的变量名和类名。对于眼前的问题,我相信这无关紧要

const fetch = require('node-fetch');
const cheerio = require('cheerio');

const fruit_names_checklist = []
const fruit_names = [];

fruitsearch = (callback) => {

    // defines url and search term

    const url = "https://www.google.com/search?q=types+of+"
    let fruit_name = "banana"

    // gets html of page

    findfruits(fruit_name);
    function findfruits(thefruit) {
        return fetch(`${url}${thefruit}`)
        .then(response => response.text())
        .then(body => {

            // scrapes fruit names and moves them into fruit_names array

            const $ = cheerio.load(body);
            $('.llgymd').each( (index, element) => {
                const $element = $(element);
                const names = $element.text();
                fruit_names[index] = names;
            });

            /* for loop that adds each fruit name to fruit_names_checklist 
               if it doesn't already doesn't already exist in the checklist */

            for(j = 0; j < fruit_names.length; j++){
                if(!fruit_names_checklist.includes(fruit_names[j])){
                     fruit_names_checklist.push(fruit_names[j]);
                     console.log(fruit_names_checklist);
            }}
 
                /* for loop that goes through each name in the checklist
                   and now searches each name through the same url request. */

                for(let i = 0; i < fruit_names_checklist.length; i++){

                    let fruit_name = fruit_names_checklist[i]
                    findfruits_loop(fruit_name);

                    function findfruits_loop(thefruit) {
                        return fetch(`${url}${thefruit}`)
                        .then(response => response.text())
                        .then(body => {
                            const $ = cheerio.load(body);
                            $('.llgymd').each( (index, element) => {
                                const $element = $(element);
                                const names = $element.text();
                                fruit_names[index] = names;
                            });

                            /* Again adds each fruit name found to fruit_names_checklist 
                               if it doesn't already exist in the checklist */

                            for(j = 0; j < fruit_names.length; j++){
                                if(!fruit_names_checklist.includes(fruit_names[j])){
                                    fruit_names_checklist.push(fruit_names[j]);
                                }
                                console.log(fruit_names_checklist);
                            }
                            // where i've placed the callback
                            callback()
                        });
                    }
                }
            })
        }
    }

    fruitsearch(
    array_to_text = () => {
        // library that converts array to txt file
        const arrayToTxtFile = require('array-to-txt-file')
        const randomValue_6d = Math.floor(Math.random() * 900000)
        arrayToTxtFile(fruit_names_checklist, `backend_modules/debugging/arrays_to_txt/fruit_names_checklist-${randomValue_6d}.txt`, err => {
            if(err) {
                console.error(err)
                return }
                console.log('Array successfully wrote to txt file')});
            })
这是我在所有函数和循环运行后最接近创建txt文件的地方,如果我在整个“水果搜索”函数的末尾使用callback(),则在将任何数据添加到检查表之前创建txt文件。我尝试在这个主函数的几乎每个地方回调,要么在执行任何函数之前创建txt文件,要么在for循环中创建它

这是理想的结果

Array(1) ["Plantain"]
Array(2) ["Plantain", "Hardy banana"]
Array(3) ["Plantain", "Hardy banana", "Blue Java banana"]
Array(4) ["Plantain", "Hardy banana", "Blue Java banana", "Cavendish banana"]
Array(5) ["Plantain", "Hardy banana", "Blue Java banana", "Cavendish banana", "Musa acuminata"]
Array(6) ["Plantain", "Hardy banana", "Blue Java banana", "Cavendish banana", "Musa acuminata", "Musa balbisiana"]
Array(7) ["Plantain", "Hardy banana", "Blue Java banana", "Cavendish banana", "Musa acuminata", "Musa balbisiana", "Red banana"]
Array(8) ["Plantain", "Hardy banana", "Blue Java banana", "Cavendish banana", "Musa acuminata", "Musa balbisiana", "Red banana", "Musa velutina"]
Array(9) ["Plantain", "Hardy banana", "Blue Java banana", "Cavendish banana", "Musa acuminata", "Musa balbisiana", "Red banana", "Musa velutina", …]
Array(10) ["Plantain", "Hardy banana", "Blue Java banana", "Cavendish banana", "Musa acuminata", "Musa balbisiana", "Red banana", "Musa velutina", …]
Array(11) ["Plantain", "Hardy banana", "Blue Java banana", "Cavendish banana", "Musa acuminata", "Musa balbisiana", "Red banana", "Musa velutina", …]
Array(12) ["Plantain", "Hardy banana", "Blue Java banana", "Cavendish banana", "Musa acuminata", "Musa balbisiana", "Red banana", "Musa velutina", …]
Array(13) ["Plantain", "Hardy banana", "Blue Java banana", "Cavendish banana", "Musa acuminata", "Musa balbisiana", "Red banana", "Musa velutina", …]
Array(14) ["Plantain", "Hardy banana", "Blue Java banana", "Cavendish banana", "Musa acuminata", "Musa balbisiana", "Red banana", "Musa velutina", …]
Array(15) ["Plantain", "Hardy banana", "Blue Java banana", "Cavendish banana", "Musa acuminata", "Musa balbisiana", "Red banana", "Musa velutina", …]
Array(16) ["Plantain", "Hardy banana", "Blue Java banana", "Cavendish banana", "Musa acuminata", "Musa balbisiana", "Red banana", "Musa velutina", …]
Array(17) ["Plantain", "Hardy banana", "Blue Java banana", "Cavendish banana", "Musa acuminata", "Musa balbisiana", "Red banana", "Musa velutina", …]
Array(18) ["Plantain", "Hardy banana", "Blue Java banana", "Cavendish banana", "Musa acuminata", "Musa balbisiana", "Red banana", "Musa velutina", …]
Array(19) ["Plantain", "Hardy banana", "Blue Java banana", "Cavendish banana", "Musa acuminata", "Musa balbisiana", "Red banana", "Musa velutina", …]
Array(20) ["Plantain", "Hardy banana", "Blue Java banana", "Cavendish banana", "Musa acuminata", "Musa balbisiana", "Red banana", "Musa velutina", …]
Array(21) ["Plantain", "Hardy banana", "Blue Java banana", "Cavendish banana", "Musa acuminata", "Musa balbisiana", "Red banana", "Musa velutina", …]
Array(22) ["Plantain", "Hardy banana", "Blue Java banana", "Cavendish banana", "Musa acuminata", "Musa balbisiana", "Red banana", "Musa velutina", …]
Array(23) ["Plantain", "Hardy banana", "Blue Java banana", "Cavendish banana", "Musa acuminata", "Musa balbisiana", "Red banana", "Musa velutina", …]
Array(24) ["Plantain", "Hardy banana", "Blue Java banana", "Cavendish banana", "Musa acuminata", "Musa balbisiana", "Red banana", "Musa velutina", …]
Array(25) ["Plantain", "Hardy banana", "Blue Java banana", "Cavendish banana", "Musa acuminata", "Musa balbisiana", "Red banana", "Musa velutina", …]
Array(26) ["Plantain", "Hardy banana", "Blue Java banana", "Cavendish banana", "Musa acuminata", "Musa balbisiana", "Red banana", "Musa velutina", …]
Array(27) ["Plantain", "Hardy banana", "Blue Java banana", "Cavendish banana", "Musa acuminata", "Musa balbisiana", "Red banana", "Musa velutina", …]
Array(28) ["Plantain", "Hardy banana", "Blue Java banana", "Cavendish banana", "Musa acuminata", "Musa balbisiana", "Red banana", "Musa velutina", …]
Array(29) ["Plantain", "Hardy banana", "Blue Java banana", "Cavendish banana", "Musa acuminata", "Musa balbisiana", "Red banana", "Musa velutina", …]
Array(30) ["Plantain", "Hardy banana", "Blue Java banana", "Cavendish banana", "Musa acuminata", "Musa balbisiana", "Red banana", "Musa velutina", …]
Array(31) ["Plantain", "Hardy banana", "Blue Java banana", "Cavendish banana", "Musa acuminata", "Musa balbisiana", "Red banana", "Musa velutina", …]
Array(32) ["Plantain", "Hardy banana", "Blue Java banana", "Cavendish banana", "Musa acuminata", "Musa balbisiana", "Red banana", "Musa velutina", …]
Array(33) ["Plantain", "Hardy banana", "Blue Java banana", "Cavendish banana", "Musa acuminata", "Musa balbisiana", "Red banana", "Musa velutina", …]
Array(34) ["Plantain", "Hardy banana", "Blue Java banana", "Cavendish banana", "Musa acuminata", "Musa balbisiana", "Red banana", "Musa velutina", …]
Array(35) ["Plantain", "Hardy banana", "Blue Java banana", "Cavendish banana", "Musa acuminata", "Musa balbisiana", "Red banana", "Musa velutina", …]
Array(36) ["Plantain", "Hardy banana", "Blue Java banana", "Cavendish banana", "Musa acuminata", "Musa balbisiana", "Red banana", "Musa velutina", …]
Array(37) ["Plantain", "Hardy banana", "Blue Java banana", "Cavendish banana", "Musa acuminata", "Musa balbisiana", "Red banana", "Musa velutina", …]
Array(38) ["Plantain", "Hardy banana", "Blue Java banana", "Cavendish banana", "Musa acuminata", "Musa balbisiana", "Red banana", "Musa velutina", …]
Array(39) ["Plantain", "Hardy banana", "Blue Java banana", "Cavendish banana", "Musa acuminata", "Musa balbisiana", "Red banana", "Musa velutina", …]
Canceled
Array successfully wrote to txt file
我不能在许多嵌套函数和许多嵌套for循环的上下文中使用“callback()”。似乎我的范围在某种程度上被打破了。期待着看到我在这里做错了什么


提前谢谢

我真的不知道这是否有用,但当遇到像你这样的情况时,我会使用这样的计数器

fruitsearch = (callback) => {
  // defines url and search term

  const url = "https://www.google.com/search?q=types+of+";
  let fruit_name = "banana";

  // gets html of page

  findfruits(fruit_name);
  function findfruits(thefruit) {
    return fetch(`${url}${thefruit}`)
      .then((response) => response.text())
      .then((body) => {
        // scrapes fruit names and moves them into fruit_names array

        const $ = cheerio.load(body);
        $(".llgymd").each((index, element) => {
          const $element = $(element);
          const names = $element.text();
          fruit_names[index] = names;
        });

        /* for loop that adds each fruit name to fruit_names_checklist 
           if it doesn't already doesn't already exist in the checklist */

        for (j = 0; j < fruit_names.length; j++) {
          if (!fruit_names_checklist.includes(fruit_names[j])) {
            fruit_names_checklist.push(fruit_names[j]);
            console.log(fruit_names_checklist);
          }
        }

        /* for loop that goes through each name in the checklist
           and now searches each name through the same url request. */
        let count = fruit_names_checklist.length; // initialize the counter
        for (let i = 0; i < fruit_names_checklist.length; i++) {
          count--; // decrement 
          let fruit_name = fruit_names_checklist[i];
          findfruits_loop(fruit_name);

          function findfruits_loop(thefruit) {
            return fetch(`${url}${thefruit}`)
              .then((response) => response.text())
              .then((body) => {
                const $ = cheerio.load(body);
                $(".llgymd").each((index, element) => {
                  const $element = $(element);
                  const names = $element.text();
                  fruit_names[index] = names;
                });

                /* Again adds each fruit name found to fruit_names_checklist 
                   if it doesn't already exist in the checklist */

                for (j = 0; j < fruit_names.length; j++) {
                  if (!fruit_names_checklist.includes(fruit_names[j])) {
                    fruit_names_checklist.push(fruit_names[j]);
                  }
                  console.log(fruit_names_checklist);
                }
                // where I've placed the callback
                if (count == 0) callback(); // if all iteration are passed write the txt file
              });
          }
        }
      });
  }
};
fruitsearch=(回调)=>{
//定义url和搜索词
常量url=”https://www.google.com/search?q=types+“+”;
让水果_name=“香蕉”;
//获取页面的html
水果(水果名称);
函数findfruits(thefruit){
返回fetch(`${url}${thefruit}`)
.然后((response)=>response.text())
。然后((正文)=>{
//刮取水果名称并将其移动到水果名称数组中
const$=cheerio.load(车身);
$(“.llgymd”)。每个((索引,元素)=>{
常量$element=$(element);
常量名称=$element.text();
水果名称[索引]=名称;
});
/*将每个水果名称添加到水果名称检查表的for循环
如果它不在清单中,那么它就不在清单中*/
对于(j=0;jresponse.text())
。然后((正文)=>{
const$=cheerio.load(车身);
$(“.llgymd”)。每个((索引,元素)=>{
常量$element=$(element);
常量名称=$element.text();
水果名称[索引]=名称;
});
/*再次将找到的每个水果名称添加到水果名称检查表中
如果清单中还没有*/
对于(j=0;j
这个问题太吵了,我的眼睛都快抽搐了。尽量保持简洁,将其归结为根本问题,不要粘贴大量代码/日志。简单地说“我的回调被多次调用”就足够了。至于学习JS-callbacks,已经足够直截了当了,理解承诺和异步/等待是必须的,我建议您花时间仔细阅读并正确理解它们。没有回答我对代码的唯一反馈是:做很多函数。把问题分解。过一会儿你会看到链接功能的威力。好的,谢谢你的建议。我会调查的
fruitsearch = (callback) => {
  // defines url and search term

  const url = "https://www.google.com/search?q=types+of+";
  let fruit_name = "banana";

  // gets html of page

  findfruits(fruit_name);
  function findfruits(thefruit) {
    return fetch(`${url}${thefruit}`)
      .then((response) => response.text())
      .then((body) => {
        // scrapes fruit names and moves them into fruit_names array

        const $ = cheerio.load(body);
        $(".llgymd").each((index, element) => {
          const $element = $(element);
          const names = $element.text();
          fruit_names[index] = names;
        });

        /* for loop that adds each fruit name to fruit_names_checklist 
           if it doesn't already doesn't already exist in the checklist */

        for (j = 0; j < fruit_names.length; j++) {
          if (!fruit_names_checklist.includes(fruit_names[j])) {
            fruit_names_checklist.push(fruit_names[j]);
            console.log(fruit_names_checklist);
          }
        }

        /* for loop that goes through each name in the checklist
           and now searches each name through the same url request. */
        let count = fruit_names_checklist.length; // initialize the counter
        for (let i = 0; i < fruit_names_checklist.length; i++) {
          count--; // decrement 
          let fruit_name = fruit_names_checklist[i];
          findfruits_loop(fruit_name);

          function findfruits_loop(thefruit) {
            return fetch(`${url}${thefruit}`)
              .then((response) => response.text())
              .then((body) => {
                const $ = cheerio.load(body);
                $(".llgymd").each((index, element) => {
                  const $element = $(element);
                  const names = $element.text();
                  fruit_names[index] = names;
                });

                /* Again adds each fruit name found to fruit_names_checklist 
                   if it doesn't already exist in the checklist */

                for (j = 0; j < fruit_names.length; j++) {
                  if (!fruit_names_checklist.includes(fruit_names[j])) {
                    fruit_names_checklist.push(fruit_names[j]);
                  }
                  console.log(fruit_names_checklist);
                }
                // where I've placed the callback
                if (count == 0) callback(); // if all iteration are passed write the txt file
              });
          }
        }
      });
  }
};