为什么我的数组在访问时是空的,但在观察时是满的?

时间:2018-01-11 15:05:15

标签: javascript node.js electron

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数组。

现在,当我去测试数组以查看它是否包含任何内容时,我会得到两个非常不同的结果。

  1. 当我使用console.log(cameras);观察阵列时,控制台会显示一个阵列1设备及其属性(假设1个网络摄像头已连接并正常工作)。

  2. 当我以任何方式(console.log();for () {}cameras.forEach();)访问数组时,它不会显示任何内容,就好像数组中没有内容一样。测试数组长度也显示为0.

  3. 这是为什么?我究竟做错了什么?任何帮助将不胜感激。

    注意:我使用的是Electron 1.7.10,Node 9.2.0和NPM 5.6.0。

3 个答案:

答案 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 arrayshttps://bugs.webkit.org/show_bug.cgi?id=35801