【问题标题】:Promise condition equal承诺条件相等
【发布时间】:2019-12-15 15:20:13
【问题描述】:

我想在我的代码中等待,直到两个值相同。为此,我使用

    await new Promise((resolve, reject) => {
        if(curCount == maxTests) resolve;
    });

但我认为,这只会被调用一次。如果两个值相同,我如何才能使承诺得到解决?如何避免它永远不会发送解析?

更新: 有的请求了麻烦的功能。这是整个功能,没有它的子功能。该函数将填充 q-queue 以填充测试同步。问题在于req.body.selection.forEach 立即返回,但我想等到整个队列准备好。所以我的想法是在结尾添加一个承诺,直到当前和最大值相同。

router.post('/imgtest', async (req, res) => {

    console.log('Start Image Test');

    //Er kommt an.
    req.setTimeout(5000000); // Nach Adam Riese 83 Minuten.
    process.setMaxListeners(0);

    io = req.app.get('socketio');

    //Caluclate the max amounnt of tests
    const maxTests = req.body.selection.length * req.body.servers.length;
    var curCount = 0;


    //RETURN IF THIS IS READY. CURRENTLY IT RETURNS IMMEDIATLY
    req.body.selection.forEach(async function(entry) {

        //Jetzt erstmal die Domain aus der DB holen
        var dbUrl = await getUrl(entry);
        console.log('tapsi');

        var bildFormat = '';

        var arrQuestionmark = dbUrl.split('?');
        if(arrQuestionmark.length==2){
            if(arrQuestionmark[1].includes('&')){
                var arrAnd = arrQuestionmark[1].split('&');
                arrAnd.forEach(function(entry) {
                    if(entry.includes('format=')){
                        var arrFormat = entry.split('=');
                        bildFormat = arrFormat[1];

                    }
                });
            }
        }

        var masterName = uuidv1();
        const orgpath = path.resolve(__basedir, 'tests/downloads', masterName + '-.' + bildFormat);

        //Download the MAsterimage
        (async () => {

            await queue.add(() =>downloadImage(dbUrl, 'c11', req.body.domain,  bildFormat, orgpath) );

        })();

        req.body.servers.forEach(async function(xserver) {

            var fileName = masterName + '-' + xserver + '.' + bildFormat;

            const dpath = path.resolve(__basedir, 'tests/downloads', fileName);

            (async () => {
                await queue.add(() => downloadImage(dbUrl, xserver, req.body.domain, bildFormat, dpath));
                //console.log('Done ' + entry);
            })();

            (async () => {
                await queue.add(async() => startCompare(orgpath, dpath, 'null:').then(function(result) {
                    console.log(result);
                    curCount++;
                    messageIO(curCount,maxTests);
                }));
                //console.log('done compare ' + entry);
                //fs.unlinkSync(dpath);
            })();



        });


    });


    console.log('Need to wait');

    res.sendStatus(200);

});

【问题讨论】:

  • 好像an XY problem。您能否分享有关您要解决的问题的更多详细信息?现在这段代码并没有真正告诉我们确切的问题是什么。
  • 您所拥有的不会等到值相等。你是对的,它只会运行一次。您能否分享更多关于您要完成的工作的信息,或者更多代码?
  • 您能否发布代码来说明您如何修改 curCount 和 maxTests?
  • 我已经添加了请求的信息。希望这能更好地解释我的问题。
  • 您应该阅读一些好书或教程来解释await/async 的作用。像(async () => { await queue.add ( … ); })(); 这样的代码没有任何意义。您无需等待完成即可调用匿名async 函数。在其中,您有一个await,它对您的代码没有任何影响。这相当于只写queue.add ( … );。而req.body.selection.forEach(async function(entry) { 也是没有任何意义的东西。使用for … of 循环,或使用.map(async function(entry) {Promise.all

标签: javascript node.js promise


【解决方案1】:

你假设它只会被调用一次是正确的。一种解决方法是在函数内通过setInterval 创建一个循环 - 定期检查并解决如果为真并清除循环。

【讨论】:

    【解决方案2】:

    不太确定要达到什么目的,但可以肯定的是,Array.prototype.forEach() 不会 await,即使它的回调是异步的,并且在 new Promise(...) 构造函数中执行测试也无济于事。

    不过,好消息是,for 循环将 await

    这是带有for 循环而不是.forEach()(两次)的代码,删除了不必要的内容,并进行了整理。

    首先是一个建议...

    // https://nodejs.org/api/querystring.html
    // The querystring module provides utilities for parsing and formatting URL query strings.
    const querystring = require('querystring');
    

    ...然后:

    router.post('/imgtest', async (req, res) => {
        req.setTimeout(5000000); // Nach Adam Riese 83 Minuten.
        process.setMaxListeners(0);
        // io = req.app.get('socketio'); // not used
        const masterName = uuidv1(); // moved from inner loop
        for (i=0; i<req.body.selection.length; i++) {
            let entry = req.body.selection[i];
            let dbUrl = await getUrl(entry);
            let bildFormat = querystring.parse(dbUrl).format;
            let orgpath = path.resolve(__basedir, 'tests/downloads', `${masterName}-.${bildFormat}`);
            await queue.add(() => downloadImage(dbUrl, 'c11', req.body.domain, bildFormat, orgpath));
            for (j=0; j<req.body.servers.length; j++) {
                let xserver = req.body.servers[j];
                let dpath = path.resolve(__basedir, 'tests/downloads', `${masterName}-${xserver}.${bildFormat}`);
                await queue.add(() => downloadImage(dbUrl, xserver, req.body.domain, bildFormat, dpath));
                await queue.add(async() => startCompare(orgpath, dpath, 'null:'); // probably safe to remove `async`
                // fs.unlinkSync(dpath); // ???
            }
        }
        res.sendStatus(200);
    });
    

    这应该可以帮助您入门。我希望你还有一段路要走。至少您需要添加一个 try/catch 结构并准备将错误/状态发送回客户端。

    【讨论】:

      猜你喜欢
      • 2015-06-22
      • 2018-02-25
      • 2021-08-01
      • 2013-10-06
      • 2013-09-16
      • 2019-04-29
      • 2016-04-12
      • 2018-08-02
      • 1970-01-01
      相关资源
      最近更新 更多