我與下面的目標是:使用承諾到foreach循環內推遲延續
- 捕捉
- 掃描通過他們每個人的(按順序)的分辨率列表找到的第一個結果在一個成功的流
爲了驗證這一點,我有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;
}
}
如您所見,我使用setTimeout
最多5次遞歸。這就是事情變得棘手:
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;
}
});
};
我試圖通過決議陣列在繼續之前forEach
內等待結果。我知道我可以使用一些先進的技術,如異步/等待,如果我想要transpile - 但我現在堅持香草JS和承諾/ bluebird.js。我有什麼選擇?免責聲明 - 我對承諾不熟悉,因此上述代碼可能非常不正確。
更新:
測試是按重要性順序定義 - 這樣我就需要resolutionTests[0]
resolutionTests[1]
之前解決。
現在的問題是:您是否想要返回維度的resolutionTests的第一個,或者如果任何可以工作的resolutionTests返回維度,那麼這個維度是否可以,無所謂。後者更容易實現,因爲你可以使用'map'和'Promise.race'。前者有點難度,但你可能會使用'reduce'。在任何情況下,'forEach'都不適用 –
@OvidiuDolha我想要第一個可用於返回尺寸的resolutionTests - 它們從高到低排序,我正在尋找最大兼容分辨率。 – SB2055