Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/38.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何处理异步循环?_Javascript_Node.js_Asynchronous_Lunrjs - Fatal编程技术网

Javascript 如何处理异步循环?

Javascript 如何处理异步循环?,javascript,node.js,asynchronous,lunrjs,Javascript,Node.js,Asynchronous,Lunrjs,我目前正在从事一个项目,以基于lunr.js的JavaScript实现全文搜索客户端 问题是,我正在努力构建然后保存索引,因为我有几个异步调用 function buildIndex(rawIndex, root, indexPath = root + 'js/app/index.json') { var path = path || require('path'); var fs = fs || require('fs'), promesses = [], ig

我目前正在从事一个项目,以基于lunr.js的JavaScript实现全文搜索客户端

问题是,我正在努力构建然后保存索引,因为我有几个异步调用

    function buildIndex(rawIndex, root, indexPath = root + 'js/app/index.json') {
  var path = path || require('path');
  var fs = fs || require('fs'),
    promesses = [],
    ignore = ['node_modules'],
    files = fs.readdirSync(root);
  files.forEach(function (file) {

    if (fs.statSync(path.join(root, file)).isDirectory() && ignore.indexOf(file) == -1) {
      buildIndex(rawIndex, path.join(root, file), indexPath);
    }
    else if (file.substr(-5) === '.html' && file != 'example.html') {
      var promesse = JSDOM.fromFile(path.join(root, file)).then(dom => {

        var $ = require('../lib/_jquery')(dom.window);
        populate();
        console.log(file + " indexé");
        function populate() {
          $('h1, h2, h3, h4, h5, h6').each(function () {
            var title = $(this);
            var link = path.join(root, file).replace('..\\', '') + "#" + title.prop('id');
            var body = title.nextUntil('h1, h2, h3, h4, h5, h6');
            rawIndex.add({
              id: link,
              title: title.text().latinise(),
              body: body.text().latinise()
            });
          });
        };
      });
      promesses.push(promesse);
    }
  });
  Promise.all(promesses)
    .then(function () {
      fs.writeFileSync(indexPath, "var data = " + JSON.stringify(rawIndex), 'utf8');
    })
    .catch(function (err) {
      console.log("Failed:", err);
    });
};

提前感谢。

有四个问题:

  • 您的函数
    buildIndex
    不会
    返回承诺,因此调用它时不能等待结果
  • 遇到目录时,递归调用
    buildIndex
    ,但不要像在else情况下使用
    promesse
    那样等待结果
  • 你有
    promeses.push(promesse)调用。将承诺放入数组的想法是正确的,但您必须立即这样做,以便它在
    promise之前发生
  • 由于某种原因,您从代码中删除了
    Promise.all
基本上,函数应具有以下通用模式:

function buildIndex(…) {
  …
  var promises = paths.map(function(path) {
    if (isDir(path)) {
      return buildIndex(…);
    } else {
      return JSDOM.fromFile(…).then(…);
    }
  });
  return Promise.all(promises).then(…);
}

使用forEach并不是一个正确的选择,因为人们想要回报承诺。 因此,更明智的做法是使用.map,然后在if/else语句中返回承诺。 最后,我们必须称之为承诺。所有(承诺)都在做出。然后(…)按预期使用

我的最后一项职能:

function buildIndex(rawIndex, root, indexPath = root + 'js/app/index.json') {
  var path = path || require('path');
  var fs = fs || require('fs'),
    promises = [],
    ignore = ['node_modules'],
    files = fs.readdirSync(root);

  var promises = files.map(function (file) {
    if (fs.statSync(path.join(root, file)).isDirectory() && ignore.indexOf(file) == -1) {
      return buildIndex(rawIndex, path.join(root, file), indexPath);
    }
    else if (file.substr(-5) === '.html' && file != 'example.html') {
      return JSDOM.fromFile(path.join(root, file)).then(dom => {

        var $ = require('jquery')(dom.window);
        populate();
        console.log(file + " indexé");

        function populate() {
          $('h1, h2, h3, h4, h5, h6').each(function () {
            var title = $(this);
            var link = path.join(root, file).replace('..\\', '') + "#" + title.prop('id');
            var body = title.nextUntil('h1, h2, h3, h4, h5, h6');
            rawIndex.add({
              id: link,
              title: title.text().latinise(),
              body: body.text().latinise()
            });
          });
        };
      })
    }
  })
  return Promise.all(promises).then(function () {
    fs.writeFileSync(indexPath, "var data = " + JSON.stringify(rawIndex), 'utf8');
  });
};

感谢@Bergi的回答和帮助。

您不是在等待递归调用的结果-它不会返回承诺,您也不会将其放入数组中。@DNZLL是
rawIndex。是否添加
异步调用?@Bergi确实如此。我不知道如何正确地实现它。@JamshidAsadzadeh好吧,我不这么认为,至少文档中没有提到它:。我更愿意说问题与$('h1,h2,h3,h4,h5,h6')有关。循环中的每个()和循环。@DNZZ将您的编辑设置为3会使代码变得更糟。我不介意你把它放回去。非常感谢你从一个新的JS学习者那里抽出时间,它似乎工作得很好。