我正在创建一个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);
});
};
}
});
content.js
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
console.log(request); // The array supportedServiceContracts has NO data
});
答案 0 :(得分:1)
tab
参数而不是重新查询活动选项卡,这既多余又是错误的-用户可以在代码运行时切换选项卡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请求,而不是等待每个顺序完成。
答案 1 :(得分:0)
尝试添加到.then函数内部的数组中:
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);
});
};
或者使用您在其他地方使用的异步等待模式...
答案 2 :(得分:0)
调用方法supportedServiceContracts
时,已声明sendMessage()
的数组仍然为空。这是因为带有supportedServiceContracts.push(...)
的行在Promise
回调函数中。到sendMessage()
被调用时,甚至没有至少一个API请求承诺被解析,这意味着还没有任何东西被推送到supportedServiceContracts
。
您将必须:
supportedServiceContracts
的所有单个请求sendMessage()
。执行此操作的一种方法是利用Promise.all(),这将使您成为一个Promise,它将在作为数组传递的所有promise解决后解决。您可以在sendMessage()
的回调函数中调用Promise.all()
示例:
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();
});
请尝试与此类似,因为这只是一个伪代码,如果仅复制粘贴,可能无法直接使用。这仅是理论上的内容,无需任何测试即可直接在此处编写。