2017-03-29 3 views
0

I nächste Objekt struct haben:Prozess n Objekte jeweils durch Bedingung

{ 
1698452536:Object {url: "1", isProcessed: false} 
1701673991:Object {url: "2", isProcessed: false} 
1717724454:Object {url: "3", isProcessed: false} 
1756233961:Object {url: "4", isProcessed: false} 
1797093325:Object {url: "5", isProcessed: false} 
1857721095:Object {url: "6", isProcessed: false} 
2095153396:Object {url: "7", isProcessed: false} 
2098466246:Object {url: "8", isProcessed: false} 
2131427779:Object {url: "9", isProcessed: false} 
89975:Object {url: "10", isProcessed: false} 
21591836:Object {url: "11", isProcessed: false} 
80794211:Object {url: "12", isProcessed: false} 
116460496:Object {url: "13", isProcessed: false} 
159798435:Object {url: "14", isProcessed: false} 
223366448:Object {url: "15", isProcessed: false} 
361352239:Object {url: "16", isProcessed: false} 
498790092:Object {url: "17", isProcessed: false} 
508072650:Object {url: "18", isProcessed: false} 
514973525:Object {url: "19", isProcessed: false} 
560440401:Object {url: "20", isProcessed: false} 
} 

Ich brauche fünf inneren Objekte jedes Mal zu verarbeiten und erst nach dem ersten fünf abgeschlossen ist eine weitere fünf nehmen. Gibt es eine Möglichkeit, eine solche Implementierung durchzuführen?

UPDATE:

I `d versucht nächsten Code, um Objekt zu chunked Array zu verwandeln, aber wie Masse von Bulk-Asynchron anrufen und erst nach vollständiger Masse ist ein weiterer Erfolg nehmen?

chunkArray(Object.values(images),5).forEach((array)=>{}); 
function chunkArray(array, groupsize) { 
var sets = [], 
    chunks, i = 0; 
chunks = array.length/groupsize; 

while (i < chunks) { 
    sets[i] = array.splice(0, groupsize); 
    i++; 
} 
return sets; 

}

+0

Was meinen Sie mit "five by five"? Fünf Objekte jedes Mal oder der fünfte Index, der zehnte Index usw.? – Matansh

+0

Fünf Objekte jedes Mal – AlexBerd

+0

** asynchrone ** Verarbeitung? –

Antwort

0

Verwenden Object.keys erhalten die Schlüssel als ein Array von alle Objekt, und dann können Sie Ihre Lösung für Array tun:

var objs = { 
    1698452536:Object {url: "1", isProcessed: false} 
    1701673991:Object {url: "2", isProcessed: false} 
    1717724454:Object {url: "3", isProcessed: false} 
    1756233961:Object {url: "4", isProcessed: false} 
    1797093325:Object {url: "5", isProcessed: false} 
    1857721095:Object {url: "6", isProcessed: false} 
    2095153396:Object {url: "7", isProcessed: false} 
    2098466246:Object {url: "8", isProcessed: false} 
    2131427779:Object {url: "9", isProcessed: false} 
    89975:Object {url: "10", isProcessed: false} 
    21591836:Object {url: "11", isProcessed: false} 
    80794211:Object {url: "12", isProcessed: false} 
    116460496:Object {url: "13", isProcessed: false} 
    159798435:Object {url: "14", isProcessed: false} 
    223366448:Object {url: "15", isProcessed: false} 
    361352239:Object {url: "16", isProcessed: false} 
    498790092:Object {url: "17", isProcessed: false} 
    508072650:Object {url: "18", isProcessed: false} 
    514973525:Object {url: "19", isProcessed: false} 
    560440401:Object {url: "20", isProcessed: false} 
}; 

var keys = Object.keys(objs); 

for (var i = 0; i < keys.length; i += 5) { 
    // Do something on every five keys  
} 
+0

Ich muss URLs async über Knoten Anfrage oder http.get – AlexBerd

+0

aufrufen Das ist nicht JSON; das ist nur ein Objekt. JSON ist ein Zeichenfolgenformat. –

+0

Der Wert ist nicht JSON, aber alle Werte befinden sich in einem JSON. Und wenn ich es richtig verstehe, will er/sie jedes Mal fünf Objekte von diesem JSON bekommen. – Matansh

0

Die folgenden Versprechen basierte Lösung Transfers Chargen der Größe n = 5 Elemente zu Ihrer asynchronen Callback-Funktion und setzt fort, sobald der Callback den Abschluss meldet:

// Process items in batches of size n via callback cb: 
 
function process(items, n, cb, offset = 0) { 
 
    if (offset >= items.length) return; 
 
    new Promise((resolve, reject) => { 
 
    cb(items.slice(offset, offset + n), resolve, reject); 
 
    }).then(() => process(items, n, cb, offset + n)); 
 
} 
 

 
// Example: 
 
let items = [0,1,2,3,4,5,6,7,8,9,10,11,12]; 
 

 
process(items, 5, (batch, resolve) => { 
 
    console.log("processing " + batch); 
 
    setTimeout(resolve, 1000); // Async processig... 
 
});

Wenn Ihr asynchroner Rückruf nur ein Element gleichzeitig verarbeiten kann, möchten Sie möglicherweise 5 Versprechungen erstellen und warten bis all have resolved, bevor Sie zum nächsten Stapel zurückkehren.

1

Hier ist ein Skelett von dem, was Sie brauchen. Ich habe versucht, die Funktionen und Variablen so zu benennen, dass sie selbsterklärend sind.

'use strict'; 
 

 
let toProcess = { 
 
\t '1698452536': { url: "1", isProcessed: false }, 
 
\t '1701673991': { url: "2", isProcessed: false }, 
 
\t '1717724454': { url: "3", isProcessed: false }, 
 
\t '1756233961': { url: "4", isProcessed: false }, 
 
\t '1797093325': { url: "5", isProcessed: false }, 
 
\t '1857721095': { url: "6", isProcessed: false }, 
 
\t '2095153396': { url: "7", isProcessed: false }, 
 
\t '2098466246': { url: "8", isProcessed: false }, 
 
\t '2131427779': { url: "9", isProcessed: false }, 
 
\t '89975': { url: "10", isProcessed: false }, 
 
\t '21591836': { url: "11", isProcessed: false }, 
 
\t '80794211': { url: "12", isProcessed: false }, 
 
\t '116460496': { url: "13", isProcessed: false }, 
 
\t '159798435': { url: "14", isProcessed: false }, 
 
\t '223366448': { url: "15", isProcessed: false }, 
 
\t '361352239': { url: "16", isProcessed: false }, 
 
\t '498790092': { url: "17", isProcessed: false }, 
 
\t '508072650': { url: "18", isProcessed: false }, 
 
\t '514973525': { url: "19", isProcessed: false }, 
 
\t '560440401': { url: "20", isProcessed: false } 
 
}; 
 

 
let howManyItemsInConcurrency = 5; 
 
stackProcessing(toProcess, howManyItemsInConcurrency); 
 

 
function stackProcessing(stack, concurrency){ 
 
\t let objsToProcess = Object.keys(stack).filter(objKey => !stack[objKey].isProcessed).slice(0, concurrency); 
 
\t if(!objsToProcess.length){ 
 
\t \t return console.log('Finish!'); 
 
\t } 
 

 
\t let objsBeingProcessed = objsToProcess.map(objKey => objProcessing(stack[objKey])); 
 
\t Promise.all(objsBeingProcessed) 
 
\t \t .then(result => { 
 
\t \t \t console.log('result', result); 
 
\t \t \t stackProcessing(stack, concurrency); 
 
\t \t }); 
 
} 
 

 

 
function objProcessing(obj){ 
 
\t console.log(`Processing URL: ${obj.url}`); 
 
\t return new Promise((resolve, reject) => { 
 
\t \t // Simulating some async processing happening 
 
\t \t setTimeout(() => { 
 
\t \t \t obj.isProcessed = true; 
 
\t \t \t resolve(obj); 
 
\t \t }, 1000); 
 
\t }); 
 
}

+0

Danke Mann. Sie haben mir sehr geholfen – AlexBerd

0

Dank @Diego ZoracKy, bietet er die Antwort mir die Grundlage dieses Problem zu lösen.

let processImages =() => { 
        let itemToDo = Object.values(images).filter((item) => { return !item.isProcessed }).slice(0, 5); 
        if (itemToDo.length) { 
         async.map(itemToDo, (arrayItem, callback) => { 
           try { 
            imagesize(arrayItem.url).then((result) => { 
             return callback(null, result); 
            }).catch(function(err) { 
             return callback(err); 

           } catch (e) { 
            return callback(err); 
           } 
          }, 
          (errors, results) => { 
           results.forEach((result) => { 
            ... 
           }); 
           if (errors) {          
       console.log('error', '!!!!!!!!!Exception was caught!!!!!! '); 
           } 
           processImages(); 
          } 
         ) 
        } else { 
         //CONTINUE TO NEXT URL 
         } 
       } 
       //Invoke process images function first time 
      processImages();