2017-05-10 38 views
0

我有一个长时间运行的函数A()。我的函数B(){}可以随时调用。Javascript排队功能陆续完成

注意函数B不必在A之后调用。但是如果它被调用并且A正在运行,那么A必须完成。然后运行B.

我想到了promise.then(),但B可能不一定会在A之后调用。所以在这种情况下它并没有多大用处。

如何'排队'B以确保逻辑?

+0

是什么让你认为B就开始执行A完成之前?你的环境是什么?您可能想要阅读这样的内容:http://stackoverflow.com/questions/2734025/is-javascript-guaranteed-to-be-single-threaded –

+0

是A和B同步还是异步?如果它们都是同步的,你不需要做任何事情,A会停止执行B直到它完成。 –

+0

A和B都是异步的。 –

回答

1

请勿使用标志!他们完全没有必要。

也不要做任何特别的事情A()B()。只需像往常一样写下来履行职责即可。

只需以动态更新的承诺链的形式实现队列。

var q_ = Promise.resolve(); 

function queue(fn) { 
    q_ = q_.then(fn); 
    return q_; 
} 

现在你可以排队AB,或其它任何功能,如下所示:

queue(A); 
queue(B); 
queue(someOtherFunction); 

或者,如果你需要传递参数:

queue(A.bind(null, 'a', 'b', 'c')); 
queue(B.bind(null, 'x', 'y', 'z')); 
queue(someOtherFunction.bind(null, 1, 2, 3)); 

作为奖励,

  • A()B()(和其他函数)仍然可以直接调用(未列出)。
  • 您不必担心传递给queue()的函数是同步还是异步。它将与任何一个工作。

DEMO

1

做这样的事: 定义一个变量var inQueue = 0; 当A开始时,设置变量inQueue = 1,当它完成时,将其设置为inQueue = 0。现在把像

if(!inQueue) B(); 

这是一个检查将确保B就不会中断A.

1

使用一个变量,它是trueA正在运行,并在A年底被设置为false。检查B。如果它正在运行,请等待一秒钟,然后再次拨打B

var isARunning 

A() { 
    isARunning = true 
    //do the things 
    isARunning = false 
} 

B() { 
    if (isARunning) { 
    setTimeout(() => { B() }, 1000); 
    } 
    else { 
    // do more things 
    } 
}