当异步功能完成时,在NodeJS中打断While循环

时间:2017-12-16 16:37:38

标签: javascript node.js async-await ecmascript-2017

我有以下节点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)

跑步时,循环无限 '处理...' 保持打印,即使异步函数应将 asyncdone boolean 设置为true,从而打破循环,然后记录结果

我不理解什么?

2 个答案:

答案 0 :(得分:0)

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

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

答案 1 :(得分: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');