Javascript 传递或JSON.stringized时对象中的数组为空

Javascript 传递或JSON.stringized时对象中的数组为空,javascript,arrays,object,google-chrome-extension,Javascript,Arrays,Object,Google Chrome Extension,我正在创建一个Chrome扩展,其中我正在将一个对象(connectionStatus)从后台脚本发送到内容脚本。该对象包含一个数组(supportedServiceContracts),当我在content.js中记录该对象时,该数组是空的,尽管在发送之前我在background.js中记录该对象时,可以看到它有数据 为什么呢 更新: 我还应该提到,如果我对对象应用JSON.stringify(),对象的数组部分将变为空。见截图 background.js chrome.browserAct

我正在创建一个Chrome扩展,其中我正在将一个对象(connectionStatus)从后台脚本发送到内容脚本。该对象包含一个数组(supportedServiceContracts),当我在content.js中记录该对象时,该数组是空的,尽管在发送之前我在background.js中记录该对象时,可以看到它有数据

为什么呢

更新:


我还应该提到,如果我对对象应用
JSON.stringify()
,对象的数组部分将变为空。见截图

background.js

chrome.browserAction.onClicked.addListener(function(tab) {
chrome.tabs.executeScript(tab.id, { file: "axios.min.js" });
chrome.tabs.executeScript(tab.id, { file: "content.js" });

var connectionStatus = {};

chrome.tabs.query({
    active: true,
    currentWindow: true
    },
    function(tabs) {
        var tab = tabs[0];
        var url = tab.url;
        var urlString = new URL(url);
        var childHSAId = urlString.searchParams.get("childhsaid");

        if (childHSAId) {
            var healthcareFacilityHSAId = urlString.searchParams.get("hsaid");
            connectionStatus.healthcareFacilityHSAId = healthcareFacilityHSAId;
            connectionStatus.childHSAId = childHSAId;
            getConnectionStatusData(childHSAId);                
        } else {
            var healthcareFacilityHSAId = urlString.searchParams.get("hsaId");
            connectionStatus.healthcareFacilityHSAId = healthcareFacilityHSAId;
            getConnectionStatusData(healthcareFacilityHSAId);
        }

});

async function getConnectionStatusData(logicalAddress) {

    let serviceDomains = await axios.get('http://api.ntjp.se/coop/api/v1/serviceDomains.json', {
                                params: {
                                    namespace: "crm:scheduling"
                                }
                            });

    serviceDomainId = serviceDomains.data[0].id;

    let connectionPoints = await axios.get('http://api.ntjp.se/coop/api/v1/connectionPoints.json', {
                                params: {
                                    platform: "NTJP",
                                    environment: "PROD"
                                }
                            });

    connectionPointId = connectionPoints.data[0].id;

    var d = new Date(connectionPoints.data[0].snapshotTime);
    var options = { hour: '2-digit', minute:'2-digit' };

    snapshotTime = d.toLocaleDateString('se-SE', options)

    connectionStatus.snapshotTime = snapshotTime;

    let logicalAddresss = await axios.get('http://api.ntjp.se/coop/api/v1/logicalAddresss.json', {
                                params: {
                                    logicalAdress: logicalAddress,
                                    serviceConsumerHSAId: "SE2321000016-92V4",
                                    connectionPointId: connectionPointId
                                }
                            });

    if (logicalAddresss.data === undefined || logicalAddresss.data.length == 0) {

        connectionStatus.errorMessage = "HSA-id " + logicalAddress + " är inte registrerat i Ineras API för Etablerad samverkan i vården. API:t uppdaterades med data från Nationella tjänsteplattformens tjänstekatalog vid " + snapshotTime + ".";

        sendMessage();

        return;

    } else {

        logicalAddressId = logicalAddresss.data[0].id;

    }

    let serviceConsumers = await axios.get('http://api.ntjp.se/coop/api/v1/serviceConsumers.json', {
                                params: {
                                    connectionPointId: connectionPointId,
                                    logicalAddressId: logicalAddressId
                                }
                            });

    consumer = serviceConsumers.data.filter(obj => {
          return obj.hsaId === "SE2321000016-92V4"
        });

    serviceConsumerId = consumer[0].id;

    let cooperations = await axios.get('http://api.ntjp.se/coop/api/v1/cooperations.json', {
                                params: {
                                    connectionPointId: connectionPointId,
                                    logicalAddressId: logicalAddressId,
                                    serviceDomainId: serviceDomainId,
                                    serviceConsumerId: serviceConsumerId,
                                    include: "serviceContract"
                                }
                            });

    var supportedServiceContracts = [];

    cooperations.data.forEach(function(cooperation) {

        axios.get('http://api.ntjp.se/coop/api/v1/serviceProducers.json', {
                    params: {
                        connectionPointId: connectionPointId,
                        logicalAddressId: logicalAddressId,
                        serviceDomainId: serviceDomainId,
                        serviceConsumerId: serviceConsumerId,
                        serviceContractId: cooperation.serviceContract.id
                    }
        }).then(response => {

            supportedServiceContracts.push({serviceContract: cooperation.serviceContract.namespace, serviceProducerDescription: response.data[0].description, serviceProducerHSAId: response.data[0].hsaId});

        });


    });

    connectionStatus.supportedServiceContracts = supportedServiceContracts;

    sendMessage();

    function sendMessage() {

        console.log(connectionStatus); // The array supportedServiceContracts has data
        console.log(JSON.stringify(connectionStatus)); // The array supportedServiceContracts has NO data

        chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
            chrome.tabs.sendMessage(tabs[0].id, connectionStatus);
        });

    };

}
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
    console.log(request); // The array supportedServiceContracts has NO data
}))

content.js

chrome.browserAction.onClicked.addListener(function(tab) {
chrome.tabs.executeScript(tab.id, { file: "axios.min.js" });
chrome.tabs.executeScript(tab.id, { file: "content.js" });

var connectionStatus = {};

chrome.tabs.query({
    active: true,
    currentWindow: true
    },
    function(tabs) {
        var tab = tabs[0];
        var url = tab.url;
        var urlString = new URL(url);
        var childHSAId = urlString.searchParams.get("childhsaid");

        if (childHSAId) {
            var healthcareFacilityHSAId = urlString.searchParams.get("hsaid");
            connectionStatus.healthcareFacilityHSAId = healthcareFacilityHSAId;
            connectionStatus.childHSAId = childHSAId;
            getConnectionStatusData(childHSAId);                
        } else {
            var healthcareFacilityHSAId = urlString.searchParams.get("hsaId");
            connectionStatus.healthcareFacilityHSAId = healthcareFacilityHSAId;
            getConnectionStatusData(healthcareFacilityHSAId);
        }

});

async function getConnectionStatusData(logicalAddress) {

    let serviceDomains = await axios.get('http://api.ntjp.se/coop/api/v1/serviceDomains.json', {
                                params: {
                                    namespace: "crm:scheduling"
                                }
                            });

    serviceDomainId = serviceDomains.data[0].id;

    let connectionPoints = await axios.get('http://api.ntjp.se/coop/api/v1/connectionPoints.json', {
                                params: {
                                    platform: "NTJP",
                                    environment: "PROD"
                                }
                            });

    connectionPointId = connectionPoints.data[0].id;

    var d = new Date(connectionPoints.data[0].snapshotTime);
    var options = { hour: '2-digit', minute:'2-digit' };

    snapshotTime = d.toLocaleDateString('se-SE', options)

    connectionStatus.snapshotTime = snapshotTime;

    let logicalAddresss = await axios.get('http://api.ntjp.se/coop/api/v1/logicalAddresss.json', {
                                params: {
                                    logicalAdress: logicalAddress,
                                    serviceConsumerHSAId: "SE2321000016-92V4",
                                    connectionPointId: connectionPointId
                                }
                            });

    if (logicalAddresss.data === undefined || logicalAddresss.data.length == 0) {

        connectionStatus.errorMessage = "HSA-id " + logicalAddress + " är inte registrerat i Ineras API för Etablerad samverkan i vården. API:t uppdaterades med data från Nationella tjänsteplattformens tjänstekatalog vid " + snapshotTime + ".";

        sendMessage();

        return;

    } else {

        logicalAddressId = logicalAddresss.data[0].id;

    }

    let serviceConsumers = await axios.get('http://api.ntjp.se/coop/api/v1/serviceConsumers.json', {
                                params: {
                                    connectionPointId: connectionPointId,
                                    logicalAddressId: logicalAddressId
                                }
                            });

    consumer = serviceConsumers.data.filter(obj => {
          return obj.hsaId === "SE2321000016-92V4"
        });

    serviceConsumerId = consumer[0].id;

    let cooperations = await axios.get('http://api.ntjp.se/coop/api/v1/cooperations.json', {
                                params: {
                                    connectionPointId: connectionPointId,
                                    logicalAddressId: logicalAddressId,
                                    serviceDomainId: serviceDomainId,
                                    serviceConsumerId: serviceConsumerId,
                                    include: "serviceContract"
                                }
                            });

    var supportedServiceContracts = [];

    cooperations.data.forEach(function(cooperation) {

        axios.get('http://api.ntjp.se/coop/api/v1/serviceProducers.json', {
                    params: {
                        connectionPointId: connectionPointId,
                        logicalAddressId: logicalAddressId,
                        serviceDomainId: serviceDomainId,
                        serviceConsumerId: serviceConsumerId,
                        serviceContractId: cooperation.serviceContract.id
                    }
        }).then(response => {

            supportedServiceContracts.push({serviceContract: cooperation.serviceContract.namespace, serviceProducerDescription: response.data[0].description, serviceProducerHSAId: response.data[0].hsaId});

        });


    });

    connectionStatus.supportedServiceContracts = supportedServiceContracts;

    sendMessage();

    function sendMessage() {

        console.log(connectionStatus); // The array supportedServiceContracts has data
        console.log(JSON.stringify(connectionStatus)); // The array supportedServiceContracts has NO data

        chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
            chrome.tabs.sendMessage(tabs[0].id, connectionStatus);
        });

    };

}
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
    console.log(request); // The array supportedServiceContracts has NO data

}))

尝试添加到中的数组。然后函数:

cooperations.data.forEach(function(cooperation) {

    axios.get('http://api.ntjp.se/coop/api/v1/serviceProducers.json', {
                params: {
                    connectionPointId: connectionPointId,
                    logicalAddressId: logicalAddressId,
                    serviceDomainId: serviceDomainId,
                    serviceConsumerId: serviceConsumerId,
                    serviceContractId: cooperation.serviceContract.id
                }
    }).then(response => {
        supportedServiceContracts.push({serviceContract: cooperation.serviceContract.namespace, serviceProducerDescription: response.data[0].description, serviceProducerHSAId: response.data[0].hsaId});
        connectionStatus.supportedServiceContracts = supportedServiceContracts;
        sendMessage();
    });


});

function sendMessage() {

    console.log(connectionStatus); // The array supportedServiceContracts has data
    console.log(JSON.stringify(connectionStatus)); // The array supportedServiceContracts has NO data

    chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
        chrome.tabs.sendMessage(tabs[0].id, connectionStatus);
    });
};

或者使用您在别处使用的异步等待模式…

调用方法
sendMessage()
时,您声明的
supportedServiceContracts
数组仍然为空。这是因为带有
supportedServiceContracts.push(…)
的行位于
Promise
回调函数中。调用
sendMessage()
时,甚至没有解决至少一个API请求承诺,这意味着尚未将任何内容推送到
supportedServiceContracts

你必须:

  • 等待将值推送到
    supportedServiceContracts
  • 然后,在请求得到解决后,您可以安全地调用
    sendMessage()
  • 这样做的一种方法是利用它,它将使您在数组解决所有承诺之后,将解决这个承诺。您可以在Promise.all()的回调函数中调用
    sendMessage()

    例如:

    const supportedServiceContracts = [];
    const apiRequestPromises= [];
    
    cooperations.data.forEach(cooperation => {
      apiRequestPromises.push(
        axios.get('http://api.ntjp.se/coop/api/v1/serviceProducers.json', {
            params: {
                connectionPointId: connectionPointId,
                logicalAddressId: logicalAddressId,
                serviceDomainId: serviceDomainId,
                serviceConsumerId: serviceConsumerId,
                serviceContractId: cooperation.serviceContract.id
            }
        })
      );
    });
    
    Promise.all(apiRequestPromises)
      .then(responses => {
        // Populate your array first
        responses.forEach(response => {
            supportedServiceContracts.push({
                serviceContract: cooperation.serviceContract.namespace,
                serviceProducerDescription: response.data[0].description,
                serviceProducerHSAId: response.data[0].hsaId
            });
        });
        // Then do whatever you want with it
        sendMessage();
      });
    
    请尝试与此类似,因为这只是一个伪代码,如果仅复制粘贴,可能无法直接工作。这只是理论性的,直接写在这里,没有任何测试。

    • 使用完成所有网络请求后发送消息-浏览器将自动将所有请求排队并一次发出一堆请求,还有JS库,允许定制Promise.all中的并行作业数量
    • 使用browserAction.onClicked的
      选项卡
      参数,而不是重新查询活动选项卡,这既冗余又错误-用户可以在代码运行时切换选项卡
    • 使用以简单的方式使用Promise/async调用API


    另外,请尝试重新编写代码,以便使用Promise.all并行调用多个axios.get请求,而不是等待每个请求依次完成。

    我还应该提到,如果应用
    JSON.stringify(),对象的数组部分将变为空
    在对象上。发送消息后,您正在填充supportedServiceContracts数组。您在第一个console.log中看到数组内容只是因为devtools显示对原始对象的引用并动态显示其内容。解决方案是使用Promise.all-on-cooperations.data并以其then()格式发送消息。您是否尝试
    JSON.stringify(connectionStatus.supportedServiceContracts)
    查看数组本身是否无法单独解析?@wOxxOm:哦,我不知道devtools会这么做。谢谢你介意更详细地解释我该做什么吗?@Cold Cerberus:是的,我做了。它无法被解析。我想沃克索姆发现了问题。我只是不明白如何解决它。我在我的原始代码中注意到了这一点,并在那里更正了它。我现在已经在问题中更正了它。但类型不是问题所在。谢谢问题:在这两行中,您是说JSON.stringify(connectionStatus)显示一个空对象,而console.log(connectionStatus)不显示?另外,在调用chrome.tabs.sendMessage时,为什么要将connectionStatus用大括号括起来?对象不是完全空的,只是其中的数组。先生,你的眼睛很好!花括号不在我的原始代码中。我也把它们移到这里了。但这也不是问题所在。我附加了控制面板的屏幕截图。我注意到行supportedServiceContracts.push({ServiceContracts:…在promise.then函数(异步)中),但您可以直接发送消息。除非我遗漏了什么,否则您应该将sendMessage放在.then函数中。非常感谢您花费时间!当我运行该代码时,我在第1行得到了
    未捕获的引用错误:未定义浏览器。
    。正如您在第三个项目符号中看到的,该代码使用WebExtension polyfill。不要只是从互联网上运行代码,先分析它,例如阅读说明/随便什么。对不起,这东西对我来说真的很高级。我设法实现了WebExtension polyfill,因此“浏览器未定义”不见了。但我似乎无法正确地将您的代码与我的代码合并。我不能只是复制/粘贴
    /*snipped*/
    处丢失的代码块,因为内容已被封装。如果您粘贴完整的代码,我将不胜感激。我没有完整的代码,我将不得不为您返工,这超出了范围。其他答案也有问题如果你不想像这里建议的那样修改你的代码,那么很容易合并。那么background.js顶部的其他部分是错误的吗?我不能将这些东西复制/粘贴到你的代码中并让它工作?