您如何等待Promise解决/拒绝最长执行时间?下面的代码显然是错误的,它只是为了解释我想要实现的目标。我一无所知。
await doSomething();
if ( executionTime > maxExecutionTime ) {
doSomethingElse();
}
这不适用于蓝鸟的承诺。
答案 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'只是因为它的执行时间很长。理论上,你要么设置一些标志(告诉它不要继续进入其管道的下一个阶段),要么设计你的应用程序,并考虑到承诺的后果。
查看更换200
和300
间隔时会发生什么。
答案 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个函数,first
和second
。您可以在此处应用逻辑以尝试第一个函数以及何时尝试第二个函数(在我们的情况下,如果第一个函数在一定时间内没有解析,则尝试第二个函数)。
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()]);
}