@dillix

Где косяк в promise?

Доброе утро!

Использую для promise библиотеку bluebird. Когда использую console.log(tree) в функции generateTree выводится полностью сформированный массив, как и положено, но при попытке вывести его через alert(JSON.stringify(tree, '', 4)), получаю только 1 элемент, причем console.log(tree[1]) выводит undefined. Получается накосячил где-то в promise, но не могу разобраться где, да и непонятно тогда, почему console.log(tree) выводит полностью данные... Помогите пожалуйста решить проблему.

Для читабельности привожу часть кода:
import jetpack from 'fs-jetpack';
import * as path from 'path';
import Promise from 'bluebird';

const fs = Promise.promisifyAll(require('fs'));

const getAllFiles = (dir, filterFn) => {
    // default filter function accepts all files
    filterFn = filterFn || function() {return true;}
    return fs.readdirAsync(dir).then(function(list) {
        return Promise.all(list.map(function(file) {
            file = path.resolve(dir, file);
            return fs.statAsync(file).then(function(stat) {
                if (stat.isDirectory()) {
                    return getAllFiles(file, filterFn);
                } else {
                    return filterFn(file)? file : '';
                }
            });
        })).then(function(results) {
            return results.filter(function(f) {
                return !!f;
            });
        });
    }).then(function(results) {
        // flatten the array of arrays
        return Array.prototype.concat.apply([], results);
    });
}

// We will add generated tree in this array
let treeArr = [
  {id: 0, name: 'File-Browser', path: 'File-Browser', link: 'index.html', childs: []}
];

const generateTree = (dir) => {
  return getAllFiles(dir, function(f) {
    return path.extname(f) === '.html';
  })
  .then(files => {
    files.forEach(function(file) {
      fs.readFile(file, 'utf-8', function read(err, contents) {
        if (err) throw err;
        if(contents.indexOf('meta content="_index"') !== -1){
          // ToDo: Front pages
        } else {
          // All other pages
          let regexp_title = /<title>(.*?)<\/title>/i
          let regexp_chapter = /<meta chapter="(.*?)" order="([0-9]+)">/i
          let data = regexp_chapter.exec(contents);
  
          // Exclude files from algorithm without our metatags
          if(data !== null) {
            let dataChapter = data[1];
            let dataTitle = regexp_title.exec(contents)[1];
            if(dataChapter.indexOf('\\') !== -1) {
              // Add categories
              var chapters = dataChapter.split('\\'),
                  parentId = 0,
                  nodePath = '',
                  nodeId;
              for(var i=0, ilen = chapters.length; i < ilen; i++) {
                nodePath += (nodePath.length > 0 ? '\\' : '') + chapters[i];
                nodeId = addNode(nodePath, chapters[i]);
                if(treeArr[parentId].childs.indexOf(nodeId) === -1) treeArr[parentId].childs.push(nodeId);
                parentId = nodeId;
              }
  
              // Add node & attach it to category
              nodeId = addNode(nodePath + '\\' + dataTitle, dataTitle, file);
              treeArr[parentId].childs.push(nodeId);
            }
          }
        }
      });
    });

    return treeArr;
  })
  .catch(console.error);
}

generateTree(appDataDir).then( tree => {
  console.log(tree);
  console.log(tree[1]);
  alert(JSON.stringify(tree, '', 4));
});
  • Вопрос задан
  • 297 просмотров
Решения вопроса 1
0xD34F
@0xD34F
Получается накосячил где-то в promise, но не могу разобраться где

Возвращаете массив вместо другого промиза, который должен резолвится, когда массив окажется полностью заполнен.

да и непонятно тогда, почему console.log(tree) выводит полностью данные

Да понятно почему - к моменту, когда вы в консоли кликаете по массиву, все данные уже подгрузились и браузер может их отобразить.

А когда вы пытаетесь взять элемент tree[1], то разумеется его ещё нет - потому и undefined. То же самое и с преобразованием в строку - в момент вызова JSON.stringify в массиве лежит всего один элемент.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы