如何设置Promise等待的最长执行时间?

时间:2017-12-08 16:53:54

标签: javascript

您如何等待Promise解决/拒绝最长执行时间?下面的代码显然是错误的,它只是为了解释我想要实现的目标。我一无所知。

await doSomething();
if ( executionTime > maxExecutionTime ) {
    doSomethingElse();
}

这不适用于蓝鸟的承诺。

5 个答案:

答案 0 :(得分:5)

下面的代码会给你一些想法:

function doSomething(maxExecutionTime) {
    return new Promise(resolve => {
        setTimeout(() => resolve(true), 2000);  // this setTimeout simulates your async action which sould not exced maxExecutionTime
        setTimeout(() => resolve(false), maxExecutionTime);
    });
}

async function someFunc(maxExecutionTime) {
    var exced = await doSomething(maxExecutionTime);
    if (exced) {
        console.log("Doesn't exced max time");
    } else {
        console.log("Exced max time");
    }
}

someFunc(1000);
someFunc(3000);

答案 1 :(得分:2)

您可以使用Promise.race(),当其可迭代中的第一个承诺解析或拒绝时,它将立即解析/拒绝。 E.g。

const longTask = (new Promise((resolve) => {
  setTimeout(() => {
    resolve("Long task complete.");
  }, 300);
}));

const timeout = (cb, interval) => {
  return new Promise((resolve) => {
    setTimeout(() => cb(resolve), interval);
  });
};

const onTimeout = timeout((resolve) => {
  resolve("The 'maybeLongTask' ran too long!");
}, 200);

Promise.race([longTask, onTimeout]).then(console.log);

唯一的问题是你不能真正取消'longTask'只是因为它的执行时间很长。理论上,你要么设置一些标志(告诉它不要继续进入其管道的下一个阶段),要么设计你的应用程序,并考虑到承诺的后果。

查看更换200300间隔时会发生什么。

答案 2 :(得分:0)

在ECMA6中您可以执行以下操作:

let promise = new Promise((resolve, reject) => {
  let wait = setTimeout(() => {
    clearTimeout(wait);
    resolve('Timed out after 200 ms..');
  }, 200)
})

答案 3 :(得分:0)

正如noahnu建议的那样,你可以使用Promise.race。你可以把它包装在一个承诺的函数中。

使用一些语法糖,你可以使用thisOrThat logic,这个函数需要2个函数,firstsecond。您可以在此处应用逻辑以尝试第一个函数以及何时尝试第二个函数(在我们的情况下,如果第一个函数在一定时间内没有解析,则尝试第二个函数)。

thisOr然后接受一个参数first,它是一个返回一个promise的函数(在我们的例子中是doSomething

thisOrThat返回一个具有or属性的对象,该属性接受一个返回promise的函数。该参数名为second,并作为logic传递给second(在我们的例子中为doSomethingElse)。

var timeoutPromise =
  time    =>
  promiseFn =>
    Promise.race([
      promiseFn(),
      new Promise(
        (_,r)=>
          setTimeout(
            _=>r("timed out")
            ,time
          )
        )
    ]);

var thisOrThat =
  logic     =>
  first  => ({
    or:second=>
      logic(first)(second)
  });
var within75ms = thisOrThat
  (first=>second=>
    timeoutPromise(75)(first)
    .catch(_=>second())
  );
var within25ms = thisOrThat
  (first=>second=>
    timeoutPromise(25)(first)
    .catch(_=>second())
  );

var doSomething = () =>
  console.log("do something called")||
  new Promise(r=>setTimeout(x=>r("something"),50));
var doSomethingElse = () =>
  console.log("do something else called") ||
  new Promise(r=>setTimeout(x=>r("something else"),50));


async function someFunc() {
  const doesNotTimeOut = 
    await within75ms(doSomething).or(doSomethingElse);
  console.log("within 75ms resolved to:",doesNotTimeOut);

  const doesTimeOut = 
    await within25ms(doSomething).or(doSomethingElse)
  console.log("within 25ms resolved to:",doesTimeOut);
};
someFunc();

答案 4 :(得分:0)

我用过Promise.race

// Try to get config from mongo
async function getProjectConfigThreshold(projectName) {
    function onTimeoutResolveDefaultThreshold() {
        return new Promise(async (resolve) => {
            setTimeout(() => {
                resolve(DEFAULT_THRESHOLD);
            }, 2000)
        });
    }

    async function getThresholdFromProjectConfig() {
        const projectConfig = await getProjectsConfig(projectName);
        const threshold = projectConfig.threshold || DEFAULT_THRESHOLD;
        return threshold;
    }

    return await Promise.race([getThresholdFromProjectConfig(), onTimeoutResolveDefaultThreshold()]);
}