我正在开发一个本地Node.js应用程序,该应用程序需要访问Google Chrome cookie。我已经找到了chrome-cookies-secure
库,它似乎可以完成这项工作,但我就是不知道下面的代码出了什么问题。
const chrome = require('chrome-cookies-secure');
const domains = [
"google.com"
];
const resolveCookies = async () => {
let result = [];
for(domain of domains) {
await chrome.getCookies(`https://${domain}/`, (err, cookies) => {
result.push(cookies);
// console.log(cookies); //? This is going to correctly print the results
})
}
return result;
}
const final = resolveCookies();
console.log(final); //! This is going to return a Promise { <pending> } object
我的想法是,我只想将所有域的cookie存储在一个列表中,但无论如何我都无法解决Promise。我没有看到这个模块的异步调用的任何例子,但如果我不使用它,它会在脚本执行后返回一个空列表。
我的节点版本:v14.4.0
我做错了什么?
看起来getCookies
的实现不是正确地等待异步进程。您可以在实现中看到,尽管getCookies
本身是async
,但它调用getDerivedKey
而不等待它(而且该函数无论如何都不是async
(。
与其试图依赖这个实现,我建议使用Util.promisify
通过回调创建一个适当的promise:
const util = require('util');
const chrome = require('chrome-cookies-secure');
const getCookies = util.promisify(chrome.getCookies);
// ...
const cookies = await getCookies(`https://${domain}/`);
请注意,正如Reece Daniels在评论中指出的那样,getCookies
实现实际上在回调之后接受了一个profile
参数;如果需要使用该参数,则不能使用内置的promisify
。你必须自己包装,这可能看起来像:
const getCookies = (url, format, profile) => new Promise((resolve, reject) => {
chrome.getCookies(url, format, (err, cookies) => {
if (err) {
reject(err);
} else {
resolve(cookies);
}
}, profile);
});
他们已经试图在上游解决这一承诺,但公关部门已经近九个月没有合并了。
注意,一旦你有一个工作函数要调用,你也可以转换:
const resolveCookies = async () => {
let result = [];
for(domain of domains) {
await chrome.getCookies(`https://${domain}/`, (err, cookies) => {
result.push(cookies);
// console.log(cookies); //? This is going to correctly print the results
})
}
return result;
}
简单地说:
const resolveCookies = () => Promise.all(domains.map((domain) => getCookies(`https://${domain}/`)));
async
函数返回一个Promise
。因此,正如您所注意到的,您的resolveCookies
函数也将返回一个Promise
。
您需要将console.log
与.then
连锁,例如
resolveCookies().then(console.log);
或者,如果您需要将其设置为类似final
的变量,您也需要等待Promise
。在这种情况下,您需要async
IIFE:
(async () => {
const final = await resolveCookies();
console.log(final);
})();
试试这个。
const chrome = require('chrome-cookies-secure');
const domains = [
"www.google.com"
];
const resolveCookies = async() => {
let result = [];
for (domain of domains) {
const cookies = await getCookies(domain)
result.push(cookies)
}
return Promise.resolve(result);
}
const getCookies = async (domain) => {
chrome.getCookies(`https://${domain}/`, (err, cookies) => {
return Promise.resolve(cookies);
})
}
resolveCookies().then((resp) => {
console.log('FINAL ',resp)
}).catch((e) => {
console.log('ERROR ', e)
})