Schrodinger的阵列:我的阵列是空的还是已满?
我在访问代码中的特定数组时遇到问题。当我观察数组时,它将正确观察并通过控制台显示内容。但是,当我访问数组时,它不会让我,因为数组没有内容供我访问。我做错了什么?
以下代码:
'use strict';
const DEBUG = true;
document.onreadystatechange = function () {
if (document.readyState === 'complete') {
if (DEBUG) {
console.log('Info: Loading is complete.');
}
main();
}
}
let main = function () {
if (DEBUG) {
console.log('Info: Running main thread.');
}
let cameras = [];
let devices = navigator.mediaDevices.enumerateDevices().then(function (devices) {
for (let i = 0; i < devices.length; i++) {
let device = devices[i];
if (device.kind === 'videoinput') {
cameras.push(device);
}
}
});
console.log(cameras);
console.log('cameras.length: ' + cameras.length);
for (let i = 0; i < cameras.length; i++) {
console.log('Loop' + i);
console.log(cameras[i]);
}
console.log(cameras);
}
控制台的输出:
app.js:8 Info: Loading is complete.
app.js:17 Info: Running main thread.
app.js:32 []
0: MediaDeviceInfodeviceId: "881b49d744ed5bcf922d1cb834c33eaab43f31fcb955c2a4e6938a2a3fb3a46c"
groupId: ""
kind: "videoinput"
label: "Logitech HD Webcam C615 (046d:082c)"
__proto__: MediaDeviceInfodeviceId: (...)
length: 1
__proto__: Array(0)
app.js:33 cameras.length: 0
app.js:40 []
0: MediaDeviceInfodeviceId: "881b49d744ed5bcf922d1cb834c33eaab43f31fcb955c2a4e6938a2a3fb3a46c"
groupId: ""
kind: "videoinput"
label: "Logitech HD Webcam C615 (046d:082c)"
__proto__: MediaDeviceInfodeviceId: (...)
length: 1
__proto__: Array(0)
代码很简单,它等待DOM完全加载并准备就绪(这里没有jQuery)。然后它执行函数main()
。此函数创建数组cameras
,然后提取所有连接的设备,并仅将videoinput
设备推送到cameras
数组。
现在,当我去测试数组以查看它是否包含任何内容时,我会得到两个非常不同的结果。
当我使用console.log(cameras);
观察阵列时,控制台会显示一个阵列1设备及其属性(假设1个网络摄像头已连接并正常工作)。
当我以任何方式(console.log();
或for () {}
或cameras.forEach();
)访问数组时,它不会显示任何内容,就好像数组中没有内容一样。测试数组长度也显示为0.
这是为什么?我究竟做错了什么?任何帮助将不胜感激。
注意:我使用的是Electron 1.7.10,Node 9.2.0和NPM 5.6.0。
答案 0 :(得分:1)
您进行异步调用。这意味着数组还没有填写在console.log
您可能想要使用回调:
let main = function () {
if (DEBUG) {
console.log('Info: Running main thread.');
}
let cameras = [];
let devices = navigator.mediaDevices.enumerateDevices().then(function (devices) {
for (let i = 0; i < devices.length; i++) {
let device = devices[i];
if (device.kind === 'videoinput') {
cameras.push(device);
}
}
callback();
});
function callback(){
console.log(cameras);
console.log('cameras.length: ' + cameras.length);
for (let i = 0; i < cameras.length; i++) {
console.log('Loop' + i);
console.log(cameras[i]);
}
console.log(cameras);
}
}
答案 1 :(得分:1)
console.log(cameras)
显示数组,因为它在控制台中展开时不像记录时的那样,尝试使用console.log(JSON.stringify(cameras));
进行记录,看看它是如何在记录的时间。
答案 2 :(得分:0)
为了回答我对那些好奇的问题,我可以感谢Chris G指出为什么会发生这种行为而不是预期的行为。
在for循环运行时,数组为空=&gt;没有“循环”输出。当您在控制台中展开摄像机输出时,Chrome会显示当前内容,而不是当时调用.log()的内容。见这里:Google Chrome console.log() inconsistency with objects and arrays
这是有道理的,因为navigator.mediaDevices.enumerateDevices()
本质上是异步的,for loop
执行时仍然在等待其承诺的解决。
但为什么console.log(cameras);
会返回一个完整的数组呢?由于Chrome中仍未解决的错误。
请参阅此处:Google Chrome console.log() inconsistency with objects and arrays和https://bugs.webkit.org/show_bug.cgi?id=35801。