Javascript 值未定义:异步中的循环使用Promise.race等待?
我正在从事一个项目,在这个项目中,我需要暴力破解Javascript 值未定义:异步中的循环使用Promise.race等待?,javascript,node.js,promise,async-await,Javascript,Node.js,Promise,Async Await,我正在从事一个项目,在这个项目中,我需要暴力破解PDF密码 因此,PDF.js用于验证密码,而promise.race则用于运行并行函数,以使整体工作速度更快 我就是这样实施的: var sfile = "KRIS.pdf" var dBuf = fs.readFileSync(sfile); const tryCases = getCombos(alphaArray, 4); // permutation having total length 456976 var fin
PDF
密码
因此,PDF.js
用于验证密码,而promise.race
则用于运行并行函数,以使整体工作速度更快
我就是这样实施的:
var sfile = "KRIS.pdf"
var dBuf = fs.readFileSync(sfile);
const tryCases = getCombos(alphaArray, 4); // permutation having total length 456976
var finishFunction = false;
async function getPass(startAt = Number(), endAt = Number()) {
var isDone = false;
var currentPass = ''
for (let index = startAt; index < endAt; index++) {
if (finishFunctions) { return; }
currentPass = tryCases[index].join("");
await pdfjsLib.getDocument({ data: dBuf, password: currentPass }).promise
.then((r) => {
console.log('Worked: ' + currentPass);
isDone = true;
pdfjsLib.distroy();
return new Promise.resolve();
})
.catch((e) => { })
if (isDone) {
finishFunctions = true;
return currentPass;
}
}
console.log(`Hey Nothing From ${startAt} - ${endAt}`);
}
console.time('Found ');
Promise.race([
getPass(0, 100000),
getPass(100000, 200000),
getPass(200000, 300000),
getPass(300000, 400000),
getPass(400000, 456976)
])
.then((s) => { console.timeEnd('Found '); console.log('HeyThen ' + s) })
.catch((e) => console.log('Hey Error ' + e));
通过调用
返回新的Promise.resolve(currentPass)
将结果返回到然后
,而不是从ATryCase
返回。将wait myFunc.getDocument
的结果写入某个变量并返回它
const res = await myFunc.getDocument({ data: dBuf, pos: currentPass })
.promise
.then(() => {
console.log('Data is: ' + currentPass);
console.timeEnd('GotData ');
return new Promise.resolve(currentPass);
}).catch(e => { });
return res;
如果currentPass
正确,我需要中断循环并返回值
到目前为止,您的代码片段都没有这样做。您将需要使用类似于
async function ATryCase(indexStart, indexEnd) {
for (let index = indexStart; index < indexEnd; index++) {
var currentPass = startLetters + index;
try {
await myFunc.getDocument({ data: dBuf, pos: currentPass }).promise;
console.log('Data is: ' + currentPass);
return currentPass; // this breaks the loop and `return`s from ATryCase
} catch {
continue;
}
}
throw new Error("No pass did find a result");
}
您的原始代码(只有一个循环)不使用
await
,将同时触发所有myFunc.getDocument(…)
调用。您的ATryCase
函数按顺序执行调用(一个接一个地等待它们),因此如果有什么问题,它应该会慢一些。如果这两个函数占用相同的时间,则表明您的getDocument
函数仍然执行内部排队,几乎没有改进的余地。如果您的ATryCase
函数访问多个文档(而不仅仅是一个文档),您希望它返回什么值?1。我从来没有说过我的单循环使用wait。我说了为什么普通循环和基于承诺的循环需要相同的时间,而基于承诺的循环被划分为多个作业。2. myFunc.getDocument
是一个基于承诺的函数,如果我不在上面使用wait,那么函数就乱七八糟了。getDocument做的不多。它只是验证currentPos
是否是要处理的正确值。把它看作是一个密码检查程序。每次验证currentPos
是否为真时,中断循环并返回currentPos。您所说的“划分为多个作业”是什么意思?每个myFunc.getDocument(…)
都已经是它自己的作业了。唯一的区别是一次叫他们所有人还是一个接一个地叫他们。不善于使用准确的词语。我的意思是使用Promise.race
。4ATryCase
每次调用30次迭代,首先找到它的人返回它。我没有得到它。重点是什么?在循环中使用它将使它在第一次迭代中退出。仅当myFunc为true或已解析时,我才需要返回当前过程。在原始代码中没有关于检查true
的代码。如果myFunc.getDocument
成功解析,则执行return res
。如果myFunc.getDocument
被拒绝,那么您将被抛出ATryCase
,您可以在catch
块外部捕获此案例。是否要返回第一次成功执行的myFunc.getDocument
,而不考虑以前被拒绝的尝试?当myFunc
解决问题时,我需要停止并返回currentPass
的值。我在函数中尝试过,但没有成功。我从不拒绝myFunc,为什么?因为我使用的是race
,其中返回了第一个解析的承诺,我只想解析一个发现值正确的承诺。我希望我解释得很好。到目前为止,您的代码片段都没有这样做
我使用基于promise的函数来做,只是想知道异步函数有什么问题。然而,这是第二个问题,主要是为什么在使用promise.race
时没有性能提升?单循环迭代89次,在450ms内完成,而多次调用函数的race也在450ms内完成。这是为什么。@ChandraShekharAazad如果“基于承诺的函数”指的是第一个片段,不,当发现某个东西时,它没有停止迭代,而且它根本没有从函数返回任何内容。它只记录它发现的结果。@ChandraShekharAazad以及为什么使用Promise.race没有任何改进,我已经在关于这个问题的评论中解释过了。原始代码没有按顺序执行任何操作,而是并行执行(同时启动所有调用)。使用wait
充其量只能意味着减速。嘿@Bergi你能看一下吗?在更新的问题上
async function ATryCase(indexStart, indexEnd) {
for (let index = indexStart; index < indexEnd; index++) {
var currentPass = startLetters + index;
try {
await myFunc.getDocument({ data: dBuf, pos: currentPass }).promise;
console.log('Data is: ' + currentPass);
return currentPass; // this breaks the loop and `return`s from ATryCase
} catch {
continue;
}
}
throw new Error("No pass did find a result");
}
function ATryCase(indexStart, indexEnd) {
const promises = [];
for (let index = indexStart; index < indexEnd; index++) {
var currentPass = startLetters + index;
promises.push(myFunc.getDocument({ data: dBuf, pos: currentPass }).promise.then(() => {
console.log('Data is: ' + currentPass);
return currentPass;
}));
}
return Promise.any(promises);
}