2016-04-22 11 views
0

Ich habe eine asynchrone Funktion, die mehrmals in der richtigen Reihenfolge aufgerufen werden muss. Es geht darum, Bilder auf einen Server hochzuladen, aber wie gesagt, die Bilder sollten in der richtigen Reihenfolge hochgeladen werden.Q verspricht Verkettung Dinge in der richtigen Reihenfolge zu tun

Meine Funktion sieht wie folgt aus:

function uploadImage(sku,fileName) { 
    console.log("Uploading image for sku="+sku+", imageName="+fileName); 

    var deferred = Q.defer(); 

    var readStream = fs.createReadStream(rootPath+'/data/'+sku+"/"+fileName); 
    var req = request.post('http://localhost:3000/'+sku+'/upload/'+fileName); 

    readStream.pipe(req); 

    req.on('end', function() { 
     console.log("Image imageName="+fileName+" uploaded successfully."); 
     db.updateLastUploadedImage(sku,fileName).then(function (res) { 
     if(res) { 
      console.log("Table watches for sku="+sku+" updated."); 
      deferred.resolve(sku); 
     } 
     }); 
    }); 

    req.on('error',function(err) { 
     deferred.reject(err); 
    }); 

    return deferred.promise; 
    } 

Ich habe versucht, es zu bringen, auf mit den Versprechungen wie dokumentiert in https://github.com/kriskowal/q Verkettungs aber es ist nicht gut funktioniert. Irgendwie komme ich nicht zum "then" -Block. So

Ich habe versucht, eine rekursive Funktion zu machen, aber es geht auch nicht in dem „dann“ Block des Funktionsaufrufes.

Nur diese Methode funktioniert, aber sie läuft nicht in der richtigen Reihenfolge.

function uploadImages(sku) { 
    var promises = []; 

    for(var x=0; x<10; x++) { 
     promises.push(uploadImage(sku,(x+1)+".jpg"))); 
    } 

    return Q.all(promises).then(function (res) { 
     return sku; 
    }); 
} 

Meine rekursive Lösung sieht wie folgt aus:

function uploadImages(sku,current,max) { 
    var deferred = Q.defer(); 

    if(current<=max) { 
     uploadImage(sku,current+'.jpg').then(function (res) { 
     if(res) { 
      uploadImages(sku,current+1,max); 
     } 
     }, function (err) { 
     deferred.reject(); 
     }); 
    } else { 
     deferred.resolve(sku); 
    } 

    return deferred.promise; 
} 

Was ich suche ist so etwas wie dieses (aber das ist nicht die Art und Weise zu implementieren):

return uploadImage(sku,"1.jpg").then(function(res) { 
     return uploadImage(sku,"2.jpg").then(function(res) { 
     return uploadImage(sku,"3.jpg").then(function(res) { 
      return uploadImage(sku,"4.jpg").then(function(res) { 
      return uploadImage(sku,"5.jpg").then(function(res) { 
       return uploadImage(sku,"6.jpg").then(function(res) { 
       return uploadImage(sku,"7.jpg").then(function(res) { 
        return uploadImage(sku,"8.jpg").then(function(res) { 
        return uploadImage(sku,"9.jpg").then(function(res) { 
         return uploadImage(sku,"10.jpg").then(function(res) { 
         return sku; 
         }); 
        }); 
        }); 
       }); 
       }); 
      }); 
      }); 
     }); 
     }); 
    }); 

Was ist die beste Praxis für meinen Zweck?

+0

Was meinen Sie "in der richtigen Reihenfolge"? – Tuvia

+0

Zum Beispiel nach image1 hochgeladen richtig sollte es das Hochladen image2 starten – Kingalione

+1

bezogen werden: http://stackoverflow.com/questions/20100245/how-can-i-execute-array-of-promises-in-sequential-order und http: //stackoverflow.com/questions/24586110/resolve-promises-one-after-another-ie-in-sequence – rlemon

Antwort

2

Es gibt kein Konzept der „richtigen Reihenfolge“ für Asynchron-Anrufe, weil sie genau das - asynchrone und sie können an jedem beliebigen Punkt beenden.

In Ihrem den Rückruf in Q.all(promises).then(...) sollten Sie die Antworten in der Reihenfolge haben, dass Sie sie gemacht, aber die Reihenfolge der Konsolenprotokolle nicht können aufgrund ihrer asynchronen Natur in der gleichen Reihenfolge sein.


In Ihrem Fall können Sie es wahrscheinlich rekursiv:

function uploadFiles(sku, current, max) { 
    return uploadImage(sku, current + '.jpg').then(function (sku) { 
      if (current > max) { return sku; } 

      return uploadFiles(sku, current + 1, max); 
    }); 
} 

// use it 
uploadFiles('SOME_SKU', 1, 10).then(function (sku) { 
    // ALL DONE! 
}); 
-2

Versuchen Ausnahmen von dem Versprechen zu fangen.

return Q.all(promises).then(function (res) { 
    return sku; 
}) 
.catch(function (error) { 
    // Handle any error from all above steps 
}); 
+0

Ich bin nicht sicher, wie das die Frage beantwortet. – Tuvia

+0

Das Auffinden des Fehlers sollte Ihnen/uns mehr Informationen über den Fehler geben und warum das Versprechen nie erfüllt wird. –

+0

@YordanIvanov: Aber es gibt keinen Fehler in der OP-Code? Es gibt Fehler, sicher, aber nichts, was eine Ausnahme auslöst, die das Versprechen ablehnen würde. – Bergi