Fix Zotero.Utilities.Internal.getAsyncInputStream(), used by Timeline
This commit is contained in:
parent
4c9f389aa8
commit
23d4992265
|
@ -639,10 +639,6 @@ Zotero.Utilities.Internal = {
|
||||||
* @return {nsIAsyncInputStream}
|
* @return {nsIAsyncInputStream}
|
||||||
*/
|
*/
|
||||||
getAsyncInputStream: function (gen, onError) {
|
getAsyncInputStream: function (gen, onError) {
|
||||||
const funcName = 'getAsyncInputStream';
|
|
||||||
const maxOutOfSequenceSeconds = 10;
|
|
||||||
const outOfSequenceDelay = 50;
|
|
||||||
|
|
||||||
// Initialize generator if necessary
|
// Initialize generator if necessary
|
||||||
var g = gen.next ? gen : gen();
|
var g = gen.next ? gen : gen();
|
||||||
var seq = 0;
|
var seq = 0;
|
||||||
|
@ -656,92 +652,56 @@ Zotero.Utilities.Internal = {
|
||||||
os.init(pipe.outputStream, 'utf-8', 0, 0x0000);
|
os.init(pipe.outputStream, 'utf-8', 0, 0x0000);
|
||||||
|
|
||||||
|
|
||||||
pipe.outputStream.asyncWait({
|
function onOutputStreamReady(aos) {
|
||||||
onOutputStreamReady: function (aos) {
|
|
||||||
//Zotero.debug("Output stream is ready");
|
|
||||||
|
|
||||||
let currentSeq = seq++;
|
let currentSeq = seq++;
|
||||||
|
|
||||||
Zotero.spawn(function* () {
|
var maybePromise = processNextValue();
|
||||||
var lastVal;
|
// If generator returns a promise, wait for it
|
||||||
var error = false;
|
if (maybePromise.then) {
|
||||||
|
maybePromise.then(() => onOutputStreamReady(aos));
|
||||||
while (true) {
|
}
|
||||||
var data;
|
// If more data, tell stream we're ready
|
||||||
|
else if (maybePromise) {
|
||||||
|
aos.asyncWait({ onOutputStreamReady }, 0, 0, Zotero.mainThread);
|
||||||
|
}
|
||||||
|
// Otherwise close the stream
|
||||||
|
else {
|
||||||
|
aos.close();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function processNextValue(lastVal) {
|
||||||
try {
|
try {
|
||||||
let result = g.next(lastVal);
|
var result = g.next(lastVal);
|
||||||
|
|
||||||
if (result.done) {
|
if (result.done) {
|
||||||
Zotero.debug("No more data to write");
|
Zotero.debug("No more data to write");
|
||||||
aos.close();
|
return false;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
// If a promise is yielded, wait for it and pass on its value
|
|
||||||
if (result.value.then) {
|
if (result.value.then) {
|
||||||
lastVal = yield result.value;
|
return result.value.then(val => processNextValue(val));
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
// Otherwise use the return value
|
if (typeof result.value != 'string') {
|
||||||
data = result.value;
|
throw new Error("Data is not a string or promise (" + result.value + ")");
|
||||||
break;
|
}
|
||||||
|
os.writeString(result.value);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
Zotero.debug(e, 1);
|
Zotero.logError(e);
|
||||||
|
|
||||||
if (onError) {
|
if (onError) {
|
||||||
error = e;
|
try {
|
||||||
data = onError();
|
os.writeString(onError(e));
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
catch (e) {
|
||||||
Zotero.debug("Closing input stream");
|
Zotero.logError(e);
|
||||||
aos.close();
|
|
||||||
throw e;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error) {
|
|
||||||
Zotero.debug("Closing input stream");
|
|
||||||
aos.close();
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof data != 'string') {
|
|
||||||
throw new Error("Yielded value is not a string or promise in " + funcName
|
|
||||||
+ " ('" + data + "')");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make sure that we're writing to the stream in order, in case
|
|
||||||
// onOutputStreamReady is called again before the last promise completes.
|
|
||||||
// If not in order, wait a bit and try again.
|
|
||||||
var maxTries = Math.floor(maxOutOfSequenceSeconds * 1000 / outOfSequenceDelay);
|
|
||||||
while (currentSeq != seq - 1) {
|
|
||||||
if (maxTries <= 0) {
|
|
||||||
throw new Error("Next promise took too long to finish in " + funcName);
|
|
||||||
}
|
|
||||||
Zotero.debug("Promise finished out of sequence in " + funcName
|
|
||||||
+ "-- waiting " + outOfSequenceDelay + " ms");
|
|
||||||
yield Zotero.Promise.delay(outOfSequenceDelay);
|
|
||||||
maxTries--;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write to stream
|
|
||||||
Zotero.debug("Writing " + data.length + " characters");
|
|
||||||
os.writeString(data);
|
|
||||||
|
|
||||||
// Wait until stream is ready for more
|
|
||||||
aos.asyncWait(this, 0, 0, null);
|
|
||||||
}, this)
|
|
||||||
.catch(function (e) {
|
|
||||||
Zotero.debug("Error getting data for async stream", 1);
|
|
||||||
Components.utils.reportError(e);
|
|
||||||
Zotero.debug(e, 1);
|
|
||||||
os.close();
|
os.close();
|
||||||
});
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}, 0, 0, null);
|
|
||||||
|
|
||||||
|
pipe.outputStream.asyncWait({ onOutputStreamReady }, 0, 0, Zotero.mainThread);
|
||||||
return pipe.inputStream;
|
return pipe.inputStream;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user