2017-05-17 10 views
1

Ich habe Probleme mit Q-Versprechen mit rekursiven Dynamodb Aufruf, neu zu Nodejs und q, unter Berücksichtigung der Einschränkungen der Dynamodb zum Abrufen von Ergebnissen, müssen wir rekursive Abfrage ausführen, um die erforderliche Ergebnisse.Datensätze von DynamoDB rekursiv mit Q.Promises

normalerweise verwenden wir die Abfrage mit dem Q-Implementierung in etwa so wie

function getDBResults(){ 

    var q = Q.defer(); 

    var params = { 
     TableName: mytable, 
     IndexName: 'mytable-index', 

     KeyConditionExpression: 'id = :id', 
     FilterExpression: 'deliveryTime between :startTime and :endTime', 

     ExpressionAttributeValues: { 
      ':startTime': { 
       N: startTime.toString() 
      }, 

      ":endTime": { 
       N: endTime.toString() 
      }, 
      ":id": { 
       S: id.toString() 
      } 
     }, 
     Select: 'ALL_ATTRIBUTES', 
     ScanIndexForward: false, 
    }; 


    dynamodb.query(params, function(err, data) { 
      if (err) { 
       console.log('Dynamo fail ' + err); 
       q.reject(err); 
      } else { 
       console.log('DATA'+ data); 
       var results = data.Items; 
       q.resolve(results); 
      } 
     }); 
     return q.promise; 

} 



getDBResults.then(
    function(data) { 
    // handle data 
    }, 
function(err) { 
     //handle error 
    } 
); 

rekursive Abfrage verwendet ich die Ergebnisse zu bekommen, aber ich brauche diese Ergebnisse in einer anderen Funktion verwendet werden, sondern wegen der NodeJS async Natur, Die nächsten Funktionsaufrufe geschehen bereits bevor die rekursive Abfragefunktion ihren Job beendet, jetzt möchte ich, dass ich alle Ergebnisse von der rekursiven Abfragefunktion bekomme und dann als Versprechen eine neue Funktion bekomme und schließlich alle Daten handhabe.

rekursive Abfrage für Dynamodb sieht so aus.

function getDBResults(){ 

    //var q = Q.defer(); 

    params = { 
     TableName: mytable, 
     IndexName: 'mytable-index', 

     KeyConditionExpression: 'id = :id', 
     FilterExpression: 'deliveryTime between :startTime and :endTime', 

     ExpressionAttributeValues: { 
      ':startTime': { 
       N: startTime.toString() 
      }, 

      ":endTime": { 
       N: endTime.toString() 
      }, 
      ":id": { 
       S: id.toString() 
      } 
     }, 
     Select: 'ALL_ATTRIBUTES', 
     ScanIndexForward: false, 
    }; 



dynamodb.query(params, onQueryCallBack); 


} 


function onQueryCallBack(err, data) { 
if (err) { 
    console.log('Dynamo fail ' + err); 
    console.error("Could not query db" + err); 
} else { 


if (typeof data.LastEvaluatedKey != "undefined") { 
    console.log("query for more..."); 
    params.ExclusiveStartKey = data.LastEvaluatedKey; 
    dynamodb.query(params, onQueryCallBack); 
} 
data.Items.forEach(function(item) { 
    allResults.push(item); 
}); 
//console.log('NO:OF Results:' + allResults.length); 

//q.resolve(tickets); 

//}); 

}

Jetzt möchte ich, dass ich die Ergebnisse als Versprechen endlich so bekommen kann ich sie in die nächste Funktion wie diese verarbeiten kann.

getDBResults.then(
    function(data) { 
    // handle data 
    }, 
function(err) { 
     //handle error 
    } 
); 

Bitte helfen Sie mir auf diesem, sorry, wenn seine eine dumme Frage, aber rekursive Aufrufe mit dem Versprechen eine Hürde für mich gemacht hat.

Dank

+0

Wie würde 'onQueryCallBack' in der Lage sein,' q' aufzulösen, wenn es nicht in der Bereich zu sehen, die aufgeschoben? – Bergi

+0

mögliche Duplikate von [Wie konvertiere ich eine bestehende Callback-API in Versprechen?] (Http://stackoverflow.com/q/22519784/1048572) – Bergi

+0

Es ist nicht doppelt Bergi, Problem ist nicht Callback-API zu Versprechen zu konvertieren, aber es ist mehr zu rekursiver Rückruf zu Versprechen, ja onQueryCallBack ist nicht im Bereich, ich posten Fragen, warum das Problem zu lösen, wenn es eine rekursive Anrufe – nsgulliver

Antwort

1

Hier ist, wie ich das Problem lösen, Dank Bergi für Ihre Lösung auch

function getDBResults() { 
    var q = Q.defer(); 
    var dynamodb = core.getDynamoDB(); 



    params = { 
     TableName: mytable, 
     IndexName: 'mytable-index', 

     KeyConditionExpression: 'id = :id', 
     FilterExpression: 'deliveryTime between :startTime and :endTime', 

     ExpressionAttributeValues: { 
      ':startTime': { 
       N: startTime.toString() 
      }, 

      ":endTime": { 
       N: endTime.toString() 
      }, 
      ":id": { 
       S: id.toString() 
      } 
     }, 
     Select: 'ALL_ATTRIBUTES', 
     ScanIndexForward: false, 
    }; 


    var results = []; 
    var callback = function(err, data) { 
     if (err) { 
      console.log('Dynamo fail ' + err); 
      q.reject(err); 
     } else if (data.LastEvaluatedKey) { 
      params.ExclusiveStartKey = data.LastEvaluatedKey; 
      dynamodb.query(params, callback); 
     } else { 
      q.resolve(results); 
     } 
     data.Items.forEach(function(item) { 
      results.push(item); 
     }); 

    } 


    dynamodb.query(params, callback); 

    return q.promise; 
} 
1

Zunächst einmal halten die promisified Funktion, die Sie bereits haben. Verwenden Sie es als Baustein für die rekursive Lösung, anstatt es zu ändern!

Es könnte allerdings zwei kleine Anpassungen benötigen:

function getDBResults(startKey){ 
//     ^^^^^^^^ 
    var q = Q.defer(); 
    var params = { 
     ExclusiveStartKey: startKey, 
//  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 
     … // rest as before 
    }; 
    dynamodb.query(params, function(err, data) { 
     if (err) { 
      q.reject(err); 
     } else { 
      q.resolve(data); 
//     ^^^^ Not `data.Items` 
     } 
    }); 
    return q.promise; 
} 

Jetzt können wir verwenden, um trivialer die rekursive Lösung zu implementieren:

function getRecursiveDBResults(key) { 
    return getDBResults(key).then(function(data) { 
     if (typeof data.LastEvaluatedKey != "undefined") { 
      return getRecursiveDBResults(data.LastEvaluatedKey).then(items) { 
       return data.Items.concat(items); 
      }); 
     } else { 
      return data.Items 
     } 
    }); 
} 
+0

Danke, für die Lösung, ich habe eine Lösung bereits herausgefunden, aber Ihre Lösung ist auch wirksam :), so Ich akzeptiere – nsgulliver