简体   繁体   中英

Make calls to async function to be executed sequentially in JavaScript

How to implement send function so that calculate will be executed sequentially , with order of calls preserved?

async function calculate(value) {
  return new Promise((resolve) => {
    setTimeout(() => resolve(value * value), 1)
  })
}

async function send(value) {
  return await calculate(value)
}
  • Next call of calculate should not start until the previous call is finished.
  • Calls to calculate should arrive in the exact same order.
  • Results for await should be returned correctly.

It should work this way when the caller ignores result (we always return the result and don't care if it's used or not)

send(2)
send(3)

and for async calls too

;(async () => {
  console.log(await send(2))
  console.log(await send(3))
})()

PS

Why it's getting down-voted? It's a perfectly legitimate use case for a stateful remote service, where calculate will be the remote call. And you have to preserve the order because the remote service is stateful and results depends on the call order.

Here's how I set up async queues so that it processes things in order regardless of how they're called:

function calculate(value) {
  var reject;
  var resolve;
  var promise = new Promise((r, rr) => {
    resolve = r;
    reject = rr;
  })

  queue.add({
    value: value,
    resolve: resolve,
    reject: reject
  });

  return promise;
}

var calcluateQueue = {
  list: [], // each member of list should have a value, resolve and reject property
  add: function(obj) {
    this.list.push(obj); // obj should have a value, resolve and reject properties
    this.processNext();
  },
  processNext: async function() {
    if (this.processing) return; // stops you from processing two objects at once
    this.processing = true;
    var next = this.list.unshift(); // next is the first element on the list array
    if (!next) return;
    try {
      var result = await doSomeProcessing(next.value);
      next.resolve(result);
      this.processNext();
    } catch(e) {
      next.reject(e);
      // you can do error processing here, including conditionally putting next back onto the processing queue if you want to
      // or waiting for a while until you try again
      this.processNext();
    }    
  }
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM