Mein Ziel mit der unten ist:Promises Mit Fortsetzung innerhalb einer foreach-Schleife verschieben
- Aufnahme eine Liste von Auflösungen
- Scan durch jeden von ihnen (in der Reihenfolge) die ersten zu finden, dass die Ergebnisse in einem erfolgreichen Strom
Um dies zu testen, ich habe testVideoPresence
:
var testCounter = 0;
function testVideoPresence(videoElement) {
testCounter++;
if (testCounter >= 5) {
testCounter = 0;
return false;
}
if (!videoElement.videoWidth || videoElement.videoWidth < 10) { // check to prevent 2x2 issue
setTimeout(function() {
testVideoPresence(videoElement); // try again
}, 500);
} else if (video.videoWidth * video.videoHeight > 0) {
return true;
}
}
Wie Sie sehen können, verwende ich eine setTimeout
, um höchstens 5 mal zu rekrutieren. Dies ist, wo es kompliziert:
resolutionTestBuilder.buildTests().then(function (resolutionTests) {
// at this point, I have a set of resolutions that I want to try
resolutionTests.forEach(function (resolutionTest) {
// then I want to iterate over all of them until I find one that works
performTest(resolutionTest).then(function (result) {
video.srcObject = result.mediaStream; // start streaming to dom
if (testVideoPresence(video)) { // here is the pain point - how do I await the result of this within the forEach?
// return the dimensions
} else {
// continue scanning
}
}).catch(function (error) {
logger.internalLog(error);
});
// wait to continue until we have our result
});
}).catch(function (error) {
logger.internalLog(error);
});
function performTest(currentTest) {
return streamHelper.openStream(currentTest.device, currentTest.resolution).then(function(streamData) {
return streamData;
}).catch(function (error) {
logger.internalLog(error);
});;
};
streamHelper.openStream = function (device, resolution) {
var constraints = createVideoConstraints(device, resolution);
logger.internalLog("openStream:" + resolution.label + ": " + resolution.width + "x" + resolution.height);
return navigator.mediaDevices.getUserMedia(constraints)
.then(function (mediaStream) {
streamHelper.activeStream = mediaStream;
return { stream: mediaStream, resolution: resolution, constraints: constraints };
// video.srcObject = mediaStream; // push mediaStream into target element. This triggers doScan.
})
.catch(function (error) {
if (error.name == "NotAllowedError") {
return error.name;
} else {
return error;
}
});
};
Ich versuche im forEach
für das Ergebnis zu warten, bevor sie durch die Anordnung von Resolutionen fortzusetzen. Ich weiß, dass ich einige fortgeschrittene Techniken wie async/have verwenden kann, wenn ich transpilieren möchte - aber ich stecke fest mit Vanille JS und Versprechungen/bluebird.js für jetzt. Was sind meine Möglichkeiten? Haftungsausschluss - Ich bin neu in Versprechungen, so dass der oben genannte Code sehr falsch sein könnte.
Update:
Tests in der Reihenfolge ihrer Bedeutung definiert sind - so dass ich resolutionTests[0]
brauchen vor resolutionTests[1]
zu lösen.
die Frage ist: wollen Sie die erste der resolutionTests, die funktioniert, um die Dimensionen zurückgeben, oder ist es in Ordnung, wenn 'any 'der resolutionTests, die Arbeit die Dimensionen zurückgibt - egal welche. Letzteres ist einfacher zu implementieren, da Sie 'map' und' Promise.race' verwenden können. Ersteres ist etwas schwieriger, aber Sie würden wahrscheinlich 'reduce' verwenden. In keinem Fall ist 'forEach' geeignet –
@OvidiuDolha Ich möchte den ersten der resolutionTests, der funktioniert, um die Dimensionen zurückzugeben - sie sind von hoch nach niedrig geordnet und ich suche nach der maximal kompatiblen Auflösung. – SB2055