本文介绍了失败前轮询结果n次(尝试之间有延迟)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们需要编写一个Node.js函数,该函数轮询某个API端点以获取先前请求的计算结果.结果需要一个随机的时间才能生成,而可能根本不生成.我们希望尽快得到它,但是我也不想等待太久,这意味着在一定数量的API调用之后,我们希望函数失败(拒绝Promise). /p>

我们的代码与API之间存在一种通信方式.

const Bluebird = require('bluebird');

function getResult() {
  return new Bluebird(async function (resolve, reject) {

    let counter = 0;

    while (counter < 10) {
      await Bluebird.delay(1000);

      const res = await apiCall();
      if (res.data) {
        resolve(res.data);
      } else {
        counter += 1;
      }
    }

    reject('timeout');
  });
}

这是正确的方法吗?

解决方案

否.这是 Promise构造函数反模式的异步/等待版本!当您调用resolve时,它甚至不会停止循环,或者在引发异常时(例如,当resnull时)拒绝它.
您应该使用

async function getResult() {
  for (let counter = 0; counter < 10; counter += 1) {
    await Bluebird.delay(1000);
    const res = await apiCall();
    if (res.data) {
      return res.data;
    }
  }
  throw new Error('timeout');
}

如果您要确保返回的是Bluebird Promise,而不是本地的Promise,请将其包装在 Bluebird.method 或告诉您的编译器使用Bluebird.

We need to write a Node.js function that polls a certain API endpoint for a result of a previously requested calculation. The result takes a random time to be generated and may not me generated at all. We'd like to get it as soon as possible, but also I don't want to wait for too long, which means that after a certain number of API calls we'd like the function to fail (reject a Promise).

There is one way communication between our code and the API.

const Bluebird = require('bluebird');

function getResult() {
  return new Bluebird(async function (resolve, reject) {

    let counter = 0;

    while (counter < 10) {
      await Bluebird.delay(1000);

      const res = await apiCall();
      if (res.data) {
        resolve(res.data);
      } else {
        counter += 1;
      }
    }

    reject('timeout');
  });
}

Is this the correct approach?

解决方案

No. This is the async/await version of the Promise constructor antipattern! It won't even stop the loop when you call resolve, or reject when an exception is thrown (e.g. when res is null).
You should use

async function getResult() {
  for (let counter = 0; counter < 10; counter += 1) {
    await Bluebird.delay(1000);
    const res = await apiCall();
    if (res.data) {
      return res.data;
    }
  }
  throw new Error('timeout');
}

If you want to ensure that a Bluebird promise is returned, not a native one, wrap it in Bluebird.method or tell your transpiler to use Bluebird.

这篇关于失败前轮询结果n次(尝试之间有延迟)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-07 05:03