通过或JSON.stringified时对象中的数组为空 [英] Array in object empty when passed or JSON.stringified

查看:105
本文介绍了通过或JSON.stringified时对象中的数组为空的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm creating a Chrome Extension where I'm sending an object (connectionStatus) from a background script to a content script. The object contains an array (supportedServiceContracts), which is empty when I log the object in content.js even though I can see it has data when I log it in background.js just before I send it.

为什么?

更新:

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

I should also mention that the array part of the object gets empty if I apply JSON.stringify() on the object. See screenshot.

背景。 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);
        });

    };

}

});

content.js

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

});

推荐答案


  • 在完成<通过使用 Promise.all()-浏览器将自动使所有请求排队,并一次发出一堆,还有JS库,可自定义Promise.all中的并行作业数量。

  • 使用browserAction.onClicked的选项卡参数,而不是重新查询活动选项卡,这既是多余的又是错误的-用户可以在代码处于工作
  • 使用 WebExtension polyfill 通过Promise /调用API以简单的方式异步

    • Send the message after completing all network requests by using Promise.all() - the browser will automatically enqueue all the requests and emit just a bunch at once, also there are JS libraries that allow customizing the amount of parallel jobs in Promise.all.
    • Use the tab parameter of browserAction.onClicked instead of requerying the active tab, which is both redundant and wrong - the user may switch tabs while your code is working
    • Use the WebExtension polyfill to call the API with Promise/async in a straightforward fashion
    • browser.browserAction.onClicked.addListener(async tab => {
      
        // enqueue without waiting so we don't block the subsequent async code 
        const contentScriptReady = Promise.all([
          browser.tabs.executeScript(tab.id, {file: "axios.min.js"}),
          browser.tabs.executeScript(tab.id, {file: "content.js"}),
        ]);
      
        const connectionStatus = {};
      
        /* snipped */
      
        connectionStatus.supportedServiceContracts = await Promise.all(
          cooperations.data.map(cooperation =>
            axios.get('http://api.ntjp.se/coop/api/v1/serviceProducers.json', {
              params: {
                connectionPointId,
                logicalAddressId,
                serviceDomainId,
                serviceConsumerId,
                serviceContractId: cooperation.serviceContract.id,
              },
            }).then(response => ({
              serviceContract: cooperation.serviceContract.namespace,
              serviceProducerDescription: response.data[0].description,
              serviceProducerHSAId: response.data[0].hsaId,
            }))
          )
        );
      
        await contentScriptReady;
        browser.tabs.sendMessage(tab.id, connectionStatus);
      
      });
      

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

      P.S. Try reworking your code so that several axios.get requests are invoked in parallel by using Promise.all instead of waiting for each one to complete sequentially.

      这篇关于通过或JSON.stringified时对象中的数组为空的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆