[英]Get result of currently running async function
How to check if there is already running function and if it is exist listen to this function result;如何检查是否已经运行 function 以及是否存在,请听此 function 结果;
async function a() {
// wait 5 seconds and return foo = foo + 1;
// if A is already running await and return result of this running function A instead result;
}
If I translate the problem correctly, A
returns a promise that is asynchronously settled.如果我正确翻译问题,
A
返回一个异步解决的 promise。 While the promise is pending, all calls to a wrapper function around A
should return the currently pending promise.虽然 promise 处于挂起状态,但对围绕
A
的包装器 function 的所有调用都应返回当前挂起的 promise。
If, however, A has not been called, or a previously return promise has been settled, A should be called again.但是,如果 A 没有被调用,或者之前返回的 promise 已经解决,则应该再次调用 A。
This can be achieved by chaining off the promise returned by A, using promise handlers to determine results are no longer pending, and have the wrapper function return the chained promise. This can be achieved by chaining off the promise returned by A, using promise handlers to determine results are no longer pending, and have the wrapper function return the chained promise. This example code speeds up the process a little - four successive calls made to
a
500ms apart get the same fulfilled value from A
which is taking 2000ms to perform a mythical asynchronous task:这个示例代码稍微加快了这个过程——相隔 500 毫秒
a
四个连续调用从A
获得相同的已实现值,这需要 2000 毫秒来执行一个神话般的异步任务:
// promise a delay const delay = ms => new Promise(resolve=>setTimeout(resolve, ms)); // async function A let foo =0; async function A() { await delay( 2000); // 2 second example return foo = foo + 1; } // Wrapper function a let a; { // block scoped let promiseA; a = ()=> { return promiseA? promiseA: promiseA = A().then( data => { promiseA=null; return data }, err => { promiseA=null; throw err} ); } } // and test async function test() { for( let i=1; i < 11; ++i) { a().then( data=> console.log(`a() call ${i} fulfills with ${data}`)); await delay(500); } } test();
{
and }
gives the let
variable block scope and makes it invisible from outside.{
和}
包围的代码块给出了let
变量块 scope 并使其从外部不可见。 Other solutions are possible.then
call uses the two parameter form for brevity.then
调用使用两个参数形式。a
always receive a promise value in return - although sometimes it's pending, sometimes not.a
调用总是会收到 promise 值作为回报 - 尽管有时它处于未决状态,但有时不是。Solution解决方案
You can create class that will be execute one flow (maximum) and await result if flow already running.您可以创建 class 将执行一个流(最大)并在流已经运行时等待结果。 It may looks something like that:
它可能看起来像这样:
class OneThreadExecutor {
// Boolean variable which represents is task running right now
taskRunning = false;
// All Promise.resolve callbacks
listeners = [];
// Accept initial value
constructor(value = 0) {
this.value = value;
}
// Send [result = value + 1] after 5 sec
startNewTask = () => {
this.taskRunning = true;
setTimeout(() => {
this.taskRunning = false;
return this.sendResult();
}, 5000)
}
// Call all Promise.resolve callbacks, and pass [value + 1] to them
sendResult = () => {
for (const listener of this.listeners) {
listener(++this.value);
}
this.listeners = [];
}
// Main method that exec one task
getResult = () => new Promise(resolve => {
// Add callback to queue
this.listeners.push(resolve);
// Start new task if necessary
if (!this.taskRunning) this.startNewTask();
})
}
General concept一般概念
Async getResult
method will register promise in class' queue.异步
getResult
方法将在类队列中注册 promise。 Any successfull task execution will send result to queue.任何成功的任务执行都会将结果发送到队列。 Current task returns
value + 1
on each getResult
call and take 5 seconds for whole flow.当前任务在每个
getResult
调用上返回value + 1
,整个流程需要 5 秒。
Usage用法
const a = new OneThreadExecutor(); // value = 0 by default
// will start task#1, 5 sec left till .then call, value = 1
a.getResult().then(...)
// 2.5 sec left, task#1 is already half progress, value = 2
setTimeout(() => {
a.getResult().then(...)
}, 2500)
Async/await异步/等待
const a = new OneThreadExecutor(3); // let's set value = 3 initially
// will start task#1, 5 sec left till .then call, value = 4
a.getResult();
// wait till task#1 completed, 5 sec left, value = 5
const value = await a.getResult();
// will start task#2 bacause not task running, 5 sec left, value = 6
a.getResult();
Cons缺点
In demo solution we already expect successful task execution, without error handling, so you may need to extend it for proper error catching during task execution.在演示解决方案中,我们已经期望成功的任务执行,没有错误处理,因此您可能需要扩展它以在任务执行期间正确捕获错误。
var is_a_running = false;
function a() {
if (is_a_running == false) {
is_a_running = true
//do something
//after you have done the thing
is_a_running = false
}
else if (is_a_running == true){
result();
}
}
This is should help you这应该可以帮助你
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.