ECMAScript 2017 одновременных асин c функции с возможностью ждать подпроцессы, которые не должны быть параллельными? - PullRequest
0 голосов
/ 05 января 2020

Предположим, у нас есть несколько одновременных задач, каждая из которых выполняет по крайней мере один веб-запрос в тот или иной момент, и они требуют времени для завершения. Предположим, что они также могут или не могут в какой-то произвольный момент выполнения запустить функцию, которая возвращает обещание. Предположим, что также необходимо убедиться, что некоторые из этих обещаний никогда не будут выполняться одновременно.

Я мог бы создать единую точку встречи, где встретились бы все эти параллельные задачи, создать цепочку обещаний из тех функций, которые вернуть обещания, которые не должны выполняться одновременно, и продолжить после того, как все это будет сделано. Это имеет обратную сторону потенциального бесполезного ожидания, если некоторые из этих задач достигают места встречи значительно раньше, чем другие, но все еще предстоит много работы после места встречи.

Кроме того, я попытался реализовать простое очередь обещаний выглядит так:

function PromiseQueue() {
    var promise = Promise.resolve();

    return {
        push: function(fn) {
            promise = promise.then(fn, fn);
            return this;
        }
    }
}

Эта очередь работает, но есть проблема, связанная с тем, что я не вижу способа отправить функцию в очередь из одной из параллельных задач, а также дождаться результатов, которые будут доступно только после того, как очередь решит обработать отправленный элемент, не говоря уже о том, что обещание еще не создано в то время, когда функция отправляется в очередь, так что нечего ждать, когда функция нереста обещания отправляется в очередь .

Я бы хотел достичь вышеупомянутого, придерживаясь формата асинхронного / ожидающего ECMAScript 2017 года и обещаний ES6 в максимально возможной степени.

Ниже приведен пример описанной проблемы с 2 одновременными задачами, где subPromise1 и subPromise2 не должны выполняться одновременно, но, как написано в настоящее время, потенциально могут, но я бы хотел общее решение для произвольной число одновременных задач.

async function async1() {
    //do some long running work
    const sPResult = await subPromise1;
    //do some more long running work depending on sPResult
}

async function async2() {
    //do some different long running work
    const sPResult = await subPromise2;
    //do some more different long running work depending on sPResult
}

async function mainFunction() {
    //something
    const totalResult = await Promise.all([async1,async2]);
    //something else
}

РЕДАКТИРОВАТЬ: Вот рабочая скрипка, где можно увидеть проблему, как первоначально описано: https://jsfiddle.net/40gchrw6/

РЕДАКТИРОВАТЬ: Вот рабочее решение: https://jsfiddle.net/f2ewsugm/1/

1 Ответ

0 голосов
/ 05 января 2020

Создайте вмещающую область (класс может иметь смысл) для цепочки обещаний, которые должны выполняться последовательно. Когда вы достигнете шага, который должен быть последовательным, добавьте его в цепочку.

Class AsyncThing {
  constructor() {
    this.promises = Promise.resolve()
  }

  async async1() {
    //do some long running work
    // assuming subPromise1 is a promise-returning function that must be chained
    let sPResult
    this.promises = this.promises.then(subPromise1).then(result => sPResult = result)
    await this.promises;
    //do some more long running work depending on sPResult
  }

  async async2() {
    //do some different long running work
    // assuming subPromise2 is a promise-returning function that must be chained
    let sPResult
    this.promises = this.promises.then(subPromise2).then(result => sPResult = result)
    await this.promises;
    //do some more different long running work depending on sPResult
  }

  async mainFunction() {
    //something
    const totalResult = await Promise.all([async1,async2]);
    //something else
  }
}
...