Я пытаюсь понять контексты в Loopback 4.

Одна вещь, которая для меня не имеет смысла, это то, как Loopback может сказать, каким должен быть контекст, если когда-либо выполнялись два асинхронных запроса параллельно.

Как в:

const ctx;

for (let i = 0; i < 10; i++) {
  ctx.set("i", i);
  endpointCall();
}

async function endpointCall() {
  return new Promise((resolve) => {
    setTimeout(
      () => { resolve `The context variable i equals ${ctx.get(i)}`,
      Math.random() * 500,
    )

  });
}

Очевидно, что вышеописанное не сработает. На самом деле, я не могу себе представить, чтобы Loopback мог сказать, в каком контексте одновременно ожидаются две или более конечных точек.

Выполняет ли loopback 4.0 запросы параллельно?


В курсе: JS является однопоточным, но движки, которые запускают JS, обычно не являются таковыми. Например, движок может выполнять многопоточное чтение нескольких выборок одновременно. Он по-прежнему будет синхронно передавать данные только в среду JS.


Ясность: Что из следующего больше похоже на петлю?

Дождется ли loopback завершения последнего вызова API, прежде чем запускать следующий, или он всегда запускает их асинхронно-параллельно?

0
Seph Reed 21 Апр 2020 в 02:28

1 ответ

Нет. Но это особенность JavaScript.


Фрагмент кода кажется неполным. Следовательно, для ясности предположим, что используется следующий код:

const Context = require('@loopback/context').Context;

const ctx = new Context();

async function main() {
  for (let i = 0; i < 10; i++) {
    ctx.bind('i').to(i);

    new Promise(() => {
      setTimeout(
        async () => {
          console.log(`The context variable i equals ${await ctx.get('i')}`);
        },
        Math.random() * 500,
      )
    });
  }
}

main()

Он достигает тех же целей, что и исходный фрагмент кода:

  • Цикл 10 раз
  • Перепривязать значение «i» с шагом 1
  • Вызовите ctx.get() после "случайной" длительности
  • Помещает setTimeout в собственное обещание

Мы используем @loopback/context напрямую, так как функции-оболочки @loopback/rest вызывают их внутри.

Мы также не используем resolve, так как в этом примере нет практической разницы (мы не используем await и не используем ответ).


как Loopback может сказать, каким должен быть контекст, если когда-либо выполнялись два асинхронных запроса параллельно

Хотя ctx.get() и ctx.bind() являются асинхронными функциями, JavaScript по-прежнему является однопоточным. Это означает, что эти функции будут поставлены в очередь в цикле обработки событий и, следовательно, будут записывать или читать состояние в порядке очереди.

Однако цикл for блокирует цикл обработки событий. Это означает, что запуск другого промиса без await-инга для его разрешения приведет к тому, что этот промис будет захвачен циклом for.

Асинхронность — это не то же самое, что многопоточность. Это означает, что всегда будет очередь, и не будет такого же «состояния гонки», как в многопоточных языках программирования.

The context variable i equals 9
The context variable i equals 9
The context variable i equals 9
The context variable i equals 9
The context variable i equals 9
The context variable i equals 9
The context variable i equals 9
The context variable i equals 9
The context variable i equals 9
The context variable i equals 9
The context variable i equals 9
The context variable i equals 9
The context variable i equals 9
The context variable i equals 9
The context variable i equals 9
The context variable i equals 9
The context variable i equals 9
The context variable i equals 9
The context variable i equals 9
The context variable i equals 9

Результаты совпадают с ctx.getSync().


Поэтому LoopBack Context не обрабатывает запросы параллельно, поскольку JavaScript является однопоточным.

Дальнейшее чтение:

0
Rifa Achrinza 21 Апр 2020 в 11:24
Кажется, здесь есть недопонимание того, о чем я спрашиваю. Я отредактировал вопрос. Из вашего ответа видно, что Loopback на самом деле выполняет несколько асинхронных вызовов API в течение одного и того же промежутка времени (хотя, очевидно, однопоточного). Либо так, либо в примере будет await endpointCall().
 – 
Seph Reed
21 Апр 2020 в 19:55