锁定JavaScript异步方法

时间:2019-01-25 13:53:51

标签: javascript node.js promise async-await locking

我有一个异步方法run,它可以接受任务,但不应同时调用,因为它为每个任务产生了一个单独的资源密集型过程。

为此,我尝试实现代理功能queue,只要有新任务要运行,该功能就会被另一个模块调用。此函数应随时允许run函数中最多 个异步代码段。即每个任务都应获得一个锁,直到处理完成后才能释放。

到目前为止我的方法:

let promise;

const queue = (...args) => {
    promise = (async() => {
        try {
            await promise;
        } catch (e) {
            // returned promised is consumed elsewhere hence empty catch block
        }
        return run(...args);
    })();
    return promise;
};

const run = async (task) => {
    console.log('Running ' + task);
    // some resource intensive process is started
    return new Promise((resolve, reject) => {
        setTimeout(resolve, 2000);
    });
};

// calling module without error handling
(async() => {
    await Promise.all([1, 2, 3].map(queue));
    console.log('All tasks finished');
})();

不幸的是,这无法让我看到队列何时为空或队列中当前正在等待多少任务。

是否有更好的方法来解决此问题?

1 个答案:

答案 0 :(得分:0)

我认为您的解决方案非常好,也许您可​​以设置一些队列计数器来跟踪当前任务和队列中剩余的任务。我确实认为,如果您完全忽略Promise.allmap,也许是这样的话,可能会有点简化:

// custom Promise method that takes an array of tasks 
// and the function to run said tasks individually

Promise.each = async function(tasks, fn) {
  for (const task of tasks) {
    // you can track progress in here by updating some counter,
    // or calling some update function
    await fn(task);
  }
  console.log('All tasks finished');
};

const run = (task) => {
    console.log('Running ' + task);
    // some resource intensive process is started
    return new Promise((resolve, reject) => {
        setTimeout(() => {
          asyncLock = false;
          resolve();
        }, 2000);
    });
};

Promise.each([1, 2 ,3], run);