首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >轮询直到得到特定的结果?

轮询直到得到特定的结果?
EN

Stack Overflow用户
提问于 2017-09-14 06:56:41
回答 8查看 13.1K关注 0票数 6

我目前正在尝试使用此链接https://davidwalsh.name/javascript-polling (以及许多其他链接)将轮询添加到我的应用程序中。

我可以访问以下已经实现的api:

client.get('url')
// returns Promise with result of getting result from url
// for the application I am working on,
//     the URL returns json that looks like the following 
//     {status: DONE or IN PROGRESS, other values...}
// when status is DONE other values are what I will use in the application

client.post('url', {data: passAnyDataHere}) 
// sends a post request with result of sending data to url
// starts the specific job

我遇到的一个问题是,当我尝试修改我链接到上面的JavaScript轮询代码时,当我发现状态是完成时,我无法将结果返回到Promise之外。有人能给我一些如何做到这一点的提示吗?(轮询直到我找到一个特定值,然后返回该值供以后使用)

让我给你举个例子

export default function someFunction() {
    let a = client.get('/status');
    a.then( dataResult => 
      {
         if (dataResult.status == "DONE") {
            //** want to get other values in dataResult here 
            // and store it somewhere else for use later
         }
      });
    // ***want to work with results here.
    // need some way to get the status of what happened inside the .then(..) part
   //  eventually have to return success or failure and results to the frontend
   // (this part is already done)
 }

代码的基础是https://github.com/erikras/react-redux-universal-hot-example#server-side-data-fetching (使用React.js/node.js/Redux/等)

感谢任何提示/建议/帮助。谢谢!

另外,我正在开发的应用程序不使用JQuery。

EN

回答 8

Stack Overflow用户

发布于 2020-11-03 06:23:05

这是一个基于post polling with async/await的更具可扩展性的解决方案

只需添加以下实用程序方法:

const poll = async function (fn, fnCondition, ms) {
  let result = await fn();
  while (fnCondition(result)) {
    await wait(ms);
    result = await fn();
  }
  return result;
};

const wait = function (ms = 1000) {
  return new Promise(resolve => {
    setTimeout(resolve, ms);
  });
};

然后你可以这样叫它:

let fetchReport = () => axios.get(reportUrl);
let validate = result => !result.data.summary;
let response = await poll(fetchReport, validate, 3000);
票数 12
EN

Stack Overflow用户

发布于 2017-09-14 07:36:23

Node.js的最新版本支持异步/等待。

下面是一个使用它的例子。

async / await的一个主要优点是,它很容易理解代码,并理解其逻辑。例如,如果你想扩展它,拥有一个最大的try's特性,这将是微不足道的。(提示)这只是一个for循环:)

let count = 0;

var client = {
  get: function () {
    return new Promise(function (resolve, reject) {
      count ++;
      setTimeout(function () {
        if (count > 4) resolve({status:'DONE',otherStuff:'Other Stuff'});
        else resolve({status: `count: ${count}`});
      }, 1000);
    });
  }
}


async function someFunction() {
  while (true) {
    let dataResult = await client.get('/status');
    console.log(dataResult.status);
    if (dataResult.status == "DONE") {
      return dataResult;
    }
  }
}

(async () => { let r = await someFunction(); console.log(r); })();

票数 5
EN

Stack Overflow用户

发布于 2017-09-14 07:54:46

下面是一个使用promises和polls直到您获得所需结果的函数的示例。我还对它进行了参数化,以便您可以传入轮询间隔和超时值:

// create a promise that resolves after a short delay
function delay(t) {
    return new Promise(function(resolve) {
        setTimeout(resolve, t);
    });
}

// interval is how often to poll
// timeout is how long to poll waiting for a result (0 means try forever)
// url is the URL to request
function pollUntilDone(url, interval, timeout) {
    let start = Date.now();
    function run() {
        return client.get(url).then(function(dataResult) {
            if (dataResult.status === "DONE") {
                // we know we're done here, return from here whatever you 
                // want the final resolved value of the promise to be
                return dataResult;
            } else {
                if (timeout !== 0 && Date.now() - start > timeout) {
                    throw new Error("timeout error on pollUntilDone");
                } else {
                    // run again with a short delay
                    return delay(interval).then(run);
                }
            }
        });
    }
    return run();
}

// sample usage
// polls every 500ms for up to 30 seconds
pollUntilDone(someUrl, 500, 30 * 1000).then(function(result) {
   // have final result here 
}).catch(function(err) {
    // handle error here
});

这里的关键是链接您的承诺,这样每次您再次调用run()时,您都会返回它的值,以便它链接到先前的承诺。然后,当您最终返回一个值或抛出异常时,原始promise将获得该值或错误作为已解决的值或被拒绝的原因。

请注意,我添加了一个超时,因为您真的永远不想永远轮询,特别是在某些不可预见和重复出现的错误可能不会拒绝promise,但不会得到您想要的结果的情况下。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46208031

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档