排队js函数

时间:2016-06-27 18:26:52

标签: javascript

很抱歉,如果之前有人问这个问题 - 我还没有找到我的答案。

我有一个函数,它将一次又一次地异步调用 我需要避免并发执行此函数。

这里的例子是:

const q = // some kind of queue;

let v = 0;
const fun = (arg) => {
    console.log('v', v)
    setTimeout(() => {
        v = v + arg;
        // return true;
        q.next()
    }, 1000)
}


q.add(fun(2))
q.add(fun(3))
q.add(fun(4))
q.add(fun(5))

这是我想在最后看到的日志:

v 0
v 2
v 5
v 9
v 14

3 个答案:

答案 0 :(得分:1)

您可以使用数组。

请注意,我的代码输出与您的输出略有不同 - 我没有得到“v 14”。我不确定为什么你期望输出...你排队四个函数调用,但期望五行输出?

const q = [];

let v = 0;
function fun (arg) {
  console.log('v', v);
  setTimeout(() => {
    v = v + arg;
    var next = q.shift();
    if (next) { next(); }
  });
}

q.push(() => { fun(2); });
q.push(() => { fun(3); });
q.push(() => { fun(4); });
q.push(() => { fun(5); });

q.shift()(); // run the first one

// OUTPUT:
// v 0
// v 2
// v 5
// v 9

修改

这可能是一个更好的版本,它具有额外的优势,无论什么时候排队,它都能正常工作。在上面的代码中,您必须手动开始运行,并且一旦队列耗尽,以后不会添加任何内容。在下面的FunctionQueue类中,只要至少有一个函数要运行,就会自动执行:

class FunctionQueue {
  constructor() {
    this.queue = [];
    this.running = false;
  }

  go() {
    if (this.queue.length) {
      this.running = true;
      this.queue.shift()(() => { this.go(); });
    } else {
      this.running = false;
    }
  }

  add(func) {
    this.queue.push(func);

    if(!this.running) {
      this.go();
    }
  }
}

let v = 0;
function fun (arg, cb) {
  console.log('v', v);
  v += arg;
  setTimeout(cb, 100);
}

const q = new FunctionQueue();
// Execution will automatically start once something is enqueued.
q.add((cb) => { fun(2, cb); });
q.add((cb) => { fun(3, cb); });
q.add((cb) => { fun(4, cb); });
q.add((cb) => { fun(5, cb); });

// At this point, nothing's running anymore.

// Enqueueing something much later will resume execution again.
setTimeout(() => {
  q.add((cb) => { fun(6, cb); });
}, 1000);

// OUTPUT:
// v 0
// v 2
// v 5
// v 9
// v 15

答案 1 :(得分:0)

您可以使用Promise。第一个解析,第二个解决,等等。

let v = 0;
const fun = (arg) => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      console.log('v', v)
        v = v + arg;
        resolve(true);
    }, 1000)
  });
}

var promise = func(0);
for (var i =1; i< 10; i++){
  (function(n){
    promise = promise.then(()=>{
       return func(n);
    });
  })(i);
}

答案 2 :(得分:0)

这将从fun()开始,继续运行,同时队列中还有增量定义

const queue = [];

const fun = (start) => {
    start = start || 0
    console.log('v', start)
    setTimeout(() => {
        if(queue.length > 0) {
          const increment = queue.shift();
          fun(start + increment);
        }
    }, 1000)
}

queue.push(2)
queue.push(3)
fun()
queue.push(4)
queue.push(5)

请注意,根据您的浏览器,可能不支持const关键字,需要将其转换为ES5或替换为var关键字。