- From: Takeshi Yoshino <tyoshino@google.com>
- Date: Mon, 21 Oct 2013 20:14:52 +0900
- To: Aymeric Vitte <vitteaymeric@gmail.com>
- Cc: Kenneth Russell <kbr@google.com>, Isaac Schlueter <i@izs.me>, Jonas Sicking <jonas@sicking.cc>, Austin William Wright <aaa@bzfx.net>, Domenic Denicola <domenic@domenicdenicola.com>, "public-webapps@w3.org" <public-webapps@w3.org>
- Message-ID: <CAH9hSJastzuXRbjh-0KH0j590Ww4eJnSLA6bnRRBN4s3O2TMyw@mail.gmail.com>
Sorry for blank of ~2 weeks. On Fri, Oct 4, 2013 at 5:57 PM, Aymeric Vitte <vitteaymeric@gmail.com>wrote: > I am still not very familiar with promises, but if I take your preceeding > example: > > > var sourceStream = xhr.response; > var resultStream = new Stream(); > var fileWritingPromise = fileWriter.write(resultStream); > var encryptionPromise = crypto.subtle.encrypt(aesAlgorithmEncrypt, aesKey, > sourceStream, resultStream); > Promise.all(fileWritingPromise, encryptionPromise).then( > ... > ); > I made a mistake. The argument of Promise.all should be an Array. So, [fileWritingPromise, encryptionPromise]. > > > shoud'nt it be more something like: > > var sourceStream = xhr.response; > var encryptionPromise = crypto.subtle.encrypt(aesAlgorithmEncrypt, aesKey); > var resultStream=sourceStream.pipe(encryptionPromise); > var fileWritingPromise = fileWriter.write(resultStream); > Promise.all(fileWritingPromise, encryptionPromise).then( > ... > ); > Promises just tell the user completion of each operation with some value indicating the result of the operation. It's not destination of data. Do you think it's good to create objects representing each encrypt operation? So, some objects called "filter" is introduced and the code would be like: var pipeToFilterPromise; var encryptionFilter; var fileWriter; xhr.onreadystatechange = function() { ... } else if (this.readyState == this.LOADING) { if (this.status != 200) { ... } var sourceStream = xhr.response; encryptionFilter = crypto.subtle.createEncryptionFilter(aesAlgorithmEncrypt, aesKey); // Starts the filter. var encryptionPromise = encryptionFilter.encrypt(); // Also starts pouring data but separately from promise creation. pipeToFilterPromise = sourceStream.pipe(encryptionFilter); fileWriter = ...; // encryptionFilter works as data producer for FileWriter. var fileWritingPromise = fileWriter.write(encryptionFilter); // Set only handler for rejection now. pipeToFilterPromise.catch( function(result) { xhr.abort(); encryptionFilter.abort(); fileWriter.abort(); } ); encryptionPromise.catch( function(result) { xhr.abort(); fileWriter.abort(); } ); fileWritingPromise.catch( function(result) { xhr.abort(); encryptionFilter.abort(); } ); // As encryptionFilter will be (successfully) closed only // when XMLHttpRequest and pipe() are both successful. // So, it's ok to set handler for fulfillment now. Promise.all([encryptionPromise, fileWritingPromise]).then( function(result) { // Done everything successfully! // We come here only when encryptionFilter is close()-ed. fileWriter.close(); processFile(); } ); } else if (this.readyState == this.DONE) { if (this.status != 200) { encryptionFilter.abort(); fileWriter.abort(); } else { // Now we know that XHR was successful. // Let's close() the filter to finish encryption // successfully. pipeToFilterPromise.then( function(result) { // XMLHttpRequest closes sourceStream but pipe() // resolves pipeToFilterPromise without closing // encryptionFilter. encryptionFilter.close(); } ); } } }; xhr.send(); encryptionFilter has the same interface as normal stream but encrypts piped data. Encrypted data is readable from it. It has special methods, encrypt() and abort(). processFile() is hypothetical function must be called only when all of loading, encryption and saving to file were successful. > > or > > var sourceStream = xhr.response; > var encryptionPromise = crypto.subtle.encrypt(aesAlgorithmEncrypt, aesKey); > var hashPromise = crypto.subtle.digest(hash); > var resultStream = sourceStream.pipe([encryptionPromise,hashPromise]); > var fileWritingPromise = fileWriter.write(resultStream); > Promise.all([fileWritingPromise, resultStream]).then( > ... > ); > > and this should be: var sourceStream = xhr.response; encryptionFilter = crypto.subtle.createEncryptionFilter(aesAlgorithmEncrypt, aesKey); var encryptionPromise = encryptionFilter.crypt(); hashFilter = crypto.subtle.createDigestFilter(hash); var hashPromise = hashFilter.digest(); pipeToFiltersPromise = sourceStream.pipe([encryptionFilter, hashFilter]); var encryptedDataWritingPromise = fileWriter.write(encryptionFilter); var hashWritingPromise = Promise.all([encryptionPromise, encryptedDataWritingPromise]).then( function(result) { return fileWriter.write(hashFilter) }, ... ); Promise.all([hashPromise, hashWritingPromise]).then( function(result) { fileWriter.close(); processFile(); }, ... ); Or, we can also choose to let the writer API to create a special object that has the Stream interface for receiving input and then let encryptionFilter and hashFilter to pipe() to it. ... pipeToFiltersPromise = sourceStream.pipe([encryptionFilter, hashFilter]); var streamForFileWrite = fileWriter.createStreamForWrite(encryptionFilter); var encryptedDataWritingPromise = encryptionFilter.pipe(streamForFileWrite); var hashWritingPromise = Promise.all([encryptionPromise, encryptedDataWritingPromise]).then( function(result) { return hashFilter.pipe(streamForWrite); }, ... );
Received on Monday, 21 October 2013 11:15:41 UTC