完成异步功能时,在NodeJS中断开While循环[重复]

问题描述 投票:-1回答:2

我有以下节点js脚本:

const rp = require('request-promise')
let result = ''
let asyncdone = false
async function m() {
    return await rp.get('http://google.com')
}

m().then((html) => {
    result = html
    asyncdone = true
}).catch((e) => console.log(e))

while (!(asyncdone)) {
    console.log('processing...')
}
console.log(result)

跑步时,循环是无限的。 'processing ...'保持打印,即使异步函数应该将asyncdone布尔值设置为true,从而打破循环,然后记录结果。

我不明白的是什么?

javascript node.js async-await ecmascript-2017
2个回答
0
投票

如果您只想记录一次processing...,我会将代码更改为以下代码。

var statuslogged = false;
while (true) {
  if (!statuslogged) {
    console.log('processing...');
    statuslogged = true;
  }
  if (asyncdone) {
    console.log(result)
  }
}

0
投票

while实际上正在做正确的事情。

由于它不间断地连续检查条件并且每次都变为真,所以它在控制台上打印信息,如果它在一秒钟内完成百万次检查并且满足条件,控制台将打印字符串。

因此,我们需要添加一个超时/间隔(称为pollInterval),以便它只在所需的时间之后进行检查。

我为您的问题提供了不同的解决方案。您希望在承诺进行时显示进度/填充文本。

const rp = require('request-promise')

// The base wrapper to stop polluting the environment
async function getHTML(url) {

    // A sample filler function
    function doSomethingElse() {
        console.log(`Processing`);
    }

    // a filler function to use it later inside
    function ensureData({
        fillerFn,
        pollInterval = 500
    }) {
        let result;

        // grab the data and set it to result async
        rp.get(url)
            .then((html) => {
                result = html
            })
            .catch((e) => console.log(e))

        return new Promise(function(resolve, reject) {
            // a self-executing function
            (function waitForFoo() {
                // if there is result, resolve it and break free
                if (result) return resolve(result);

                // otherwise run the filler function
                fillerFn()

                // execute itself again after the provided time
                setTimeout(waitForFoo, pollInterval);
            })();
        });
    }

    // return or run it
    ensureData({
            fillerFn: doSomethingElse,
            pollInterval: 500
        })
        .then((result) => {
            console.log(result)
        })
}

getHTML('http://httpbin.org/ip');
© www.soinside.com 2019 - 2024. All rights reserved.