Promise.race 不适用于自定义函数

问题描述 投票:0回答:1

我有一个小型 Node.js 应用程序,它尝试使用 synchrony 对 Javascript 源代码数据集进行反混淆。

synchrony.deobfuscateNode(ast)
函数返回一个promise,因此我实现了一个
Promise.race
,以便在反混淆花费太长时间的情况下让程序返回:

const { Deobfuscator } = require('./synchrony');
const { timeout } = require('../../../config');
const { parse } = require('../../utils/parser');

async function callDeobfuscator(ast, obfuscator) {
  const withTimeout = (promise) => {
    let timeoutPid;
    const timeoutPromise = new Promise((resolve, reject) => 
      timeoutPid = setTimeout(reject, timeout));
    return Promise.race([
        promise,
        timeoutPromise
    ]).finally(() => {
        if (timeoutPid) {
          clearTimeout(timeoutPid);
        }
    });
  };
  const synchrony = new Deobfuscator();
  return await withTimeout(synchrony.deobfuscateNode(ast));
};


const fs = require('fs');
fs.readFile('script.js', 'utf8', async function(err, source){ 
  let ast = parse(source);
  ast = await callDeobfuscator(ast);
  console.log(ast);
});

但是,每当

callDeobfuscator
花费的时间超过超时承诺时,就不会抛出异常(超时承诺不会拒绝),并且程序无论如何都会等待
callDeobfuscator
解决。我尝试用另一个超时承诺替换
callDeobfuscator
逻辑 (
testPromise
):

async function callDeobfuscator(ast, obfuscator) {
  const withTimeout = (promise) => {
    let timeoutPid;
    const timeoutPromise = new Promise((resolve, reject) => 
      timeoutPid = setTimeout(reject, timeout));
    return Promise.race([
        promise,
        timeoutPromise
    ]).finally(() => {
        if (timeoutPid) {
          clearTimeout(timeoutPid);
        }
    });
  };
  const testPromise = new Promise((resolve, reject) => {
    setTimeout(resolve, 1000000000, 'two');
  });
  return await withTimeout(testPromise);
};

现在它按预期工作了,所以我猜我无法理解的

callDeobfuscator
承诺一定有问题。有什么见解吗?

node.js promise race-condition
1个回答
0
投票

我快速浏览了synchrony的源代码并查看了

deobfuscateNode
函数。

该函数使用不同的代码转换器在循环中调用

transform
。尽管这些转换器具有 async 函数签名,但我没有找到一个真正以异步方式工作的转换器(这意味着没有使用异步 IO 方法,并且在实现中甚至没有等待任何内容)。这意味着,即使从
deobfuscateNode
返回了一个 Promise,所有代码实际上都是同步执行的,并且会让 JS 解释器保持忙碌。

这意味着,一旦您开始运行

deobfuscateNode
,您将无法以任何方式中断它。为了能够做到这一点,必须改变同步库的工作方式。

© www.soinside.com 2019 - 2024. All rights reserved.