2015-04-02 2 views
0

Я только начинаю на FRP и baconjs, так что простите мое невежество по терминологии.BaconJS Структура каталогов Пример рекурсии

Я нахожусь в проекте, где я пытаюсь создать структуру каталогов на диске Google. Мне нужно обеспечить, чтобы родительские каталоги были созданы до каталогов детей, чтобы создать иерархическую структуру.

Я написал следующий код. Однако через несколько минут я столкнулся с «Ограничением скорости пользователя», которое было выбрано Google, что означает, что я слишком быстро вызываю Google слишком много запросов.

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

У кого-нибудь есть идея, как это сделать?

var _generateFolder = function(dirArray, gDrive, parentDir) { 
    // chunk array into size of 2 elements 
    var chunked = _.chunk(dirArray, 5) 
    return Bacon 
     .sequentially(1000 * 5, chunked) // Stream with all the chunks 
     .flatMapConcat(function(arrayChunk){ // Stream for all items 
      return Bacon.fromArray(arrayChunk) 
     }) 
     .flatMap(_createOrUpdateGFolder) 
     .filter(function removeAllItemsWithNoChildren(dir) { 
      return dir.children.length > 0; 
     }) 
     .flatMap(function createSubDirectoriesForItem(dir) { 
      console.log("Sync children folders:" + dir.title); 
      return _generateFolder(dir.children, gDrive, dir); 
     }) 
} 

dir = { 
    title:"A", 
    children:[ 
     { 
      title: "AA" 
      children:[ 
       { 
        title:"AAA", 
        children:[] 
       } 
      ] 
     }, 
     { 
      title: "AB" 
      children:[ 
       { 
        title:"ABA", 
        children:[] 
       }, 
       { 
        title:"ABB", 
        children:[] 
       } 
      ] 
     }, 
    ] 
} 
_generateFolder(dir, drive, null) 

Есть ли способ иметь один поток, добавлять каталоги в этот поток, рекурсивно? А затем использовать chunk + sequential в этом потоке?

ответ

0

Примечание: Это не решение, а быстрый и грязный подход.

Я бы рекурсивно прохожу через каталог JSON. Baconjs предоставляет API Bacon.fromBinder, который позволяет создавать пользовательские потоки. Каждый раз, когда я попадал в свойство «title», я бы «испускал» событие бекона. Это создаст поток событий для каждого посещенного заголовка.

var dirs = { 
 
    title: "A", 
 
    children: [{ 
 
    title: "AA", 
 
    children: [{ 
 
     title: "AAA", 
 
     children: [] 
 
    }] 
 
    }, { 
 
    title: "AB", 
 
    children: [{ 
 
     title: "ABA", 
 
     children: [] 
 
    }, { 
 
     title: "ABB", 
 
     children: [] 
 
    }] 
 
    }, ] 
 
}; 
 

 
function walk(sink, r) { 
 
    if (Array.isArray(r)) { 
 
    r.forEach(function(child) { 
 
     return walk(sink, child); 
 
    }) 
 
    } else if (typeof r === 'object') { 
 
    sink(r.title); 
 
    walk(sink, r.children); 
 
    } 
 
} 
 

 

 
Bacon.fromBinder(function(sink) { 
 
    walk(sink, dirs); 
 
    return function() { 
 
    // return a sensible unsubscribe 
 
    }; 
 
}).log(); 
 

 
// To insert into DOM - demo purposes 
 
var stream = Bacon.fromBinder(function(sink) { 
 
    walk(sink, dirs); 
 
    return function() {}; 
 
}); 
 

 
$("#events").append('<ul></ul>'); 
 
var list; 
 

 
stream.onValue(function(val) { 
 
    list = $("#events").find('ul'); 
 
    list.append("<li>" + val + "</li>"); 
 
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/bacon.js/0.7.71/Bacon.min.js"></script> 
 
<div id="events"></div>

Смежные вопросы