Проблема Powershell с порядком выполнения в скрипте

У меня проблема с неожиданным порядком запуска и возврата вещей в приведенном ниже сценарии Powershell.

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

Проблема в том, что когда я вызываю свою функцию Write-ArrayToTable, она не возвращает данные до тех пор, пока не вернется команда Read-Host.

Ниже приведен вывод запуска скрипта, а сам код ниже. Вывод таблицы должен отображаться ПЕРЕД вызовом Read-Host, но вместо этого удерживается до конца, а затем отображается.

Что мне не хватает? Любая помощь очень ценится!

Вывод:

Test: y
Label1 Label2
------ ------
Test1  Test3
Test2  Test4
y

Код:

Function Write-ArrayToTable{
  param(
      [String[]]$Names,
      [Object[][]]$Data
  )
  for($i = 0;; ++$i){
    $Props = [ordered]@{}
    for($j = 0; $j -lt $Data.Length; ++$j){
      if ($i -lt $Data[$j].Length){
        $Props.Add($Names[$j], $Data[$j][$i])
      }
    }
    if (!$Props.get_Count()){
      break
    }
    [PSCustomObject]$Props
  }
}

$arr1 = @("Test1","Test2")
$arr2 = @("Test3","Test4")

Write-ArrayToTable "Label1","Label2" $arr1,$arr2

Read-Host "Test"

Вероятно, та же основная причина, что и в этом ответе @mklement0… stackoverflow.com/a/59331305/3156906 - Format-Table может задерживать до 300 мс перед рендерингом вывода, к этому времени Read-Host уже блокируется в ожидании ответа от пользователя, чтобы вы ничего не видели, пока Read-Host не закончит.

mclayton 28.10.2022 19:16

Кроме того, нет гарантии, что ваш код будет генерировать табличный вывод — в PowerShell есть некоторые правила, которые определяют, использует ли поведение по умолчанию для форматирования вывода format-list или format-table — ваши тестовые примеры, вероятно, просто выбрали format-table, но если вы попробуете с одним вместо свойства вы можете увидеть, что оно использует format-list

mclayton 28.10.2022 19:21

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

xeric080 28.10.2022 19:29

Если вы переименуете свою функцию во что-то вроде Select-From2DArray, что более реалистично, то вы можете просто направить вывод из этого в Format-Table, и он всегда будет выводить в виде табличных данных.

mclayton 28.10.2022 19:34

Круто, у меня все работает благодаря вам и @stackprotector. Очень ценю информацию о том, что происходит под капотом. Помоги мне узнать больше!

xeric080 28.10.2022 19:41

Хотя я только что заметил, что это зубчатый массив, а не 2D-массив, так что, возможно, Select-FromJaggedArray было бы лучшим названием…

mclayton 28.10.2022 19:41

Чтобы добавить к комментариям Маклейтона: отсутствие синхронизации между выводом конвейера и выводом на хост (а также другими потоками вывода) ограничено PS v5+ и очень специфическим, хотя и все еще распространенным сценарием: неявно табличный вывод для типов, которые для них не определены данные форматирования. Неоптимальный обходной путь заключается в принудительном синхронном выводе конвейера с хостом (дисплеем) с помощью Out-Host. Подробнее см. связанный дубликат.

mklement0 28.10.2022 19:49
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
7
57
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вместо того, чтобы сбрасывать такие объекты:

[PSCustomObject]$Props

Вы можете быть более явным:

$Props | Out-String

Если вы хотите напечатать все объекты в одной таблице, сначала соберите их перед печатью:

Function Write-ArrayToTable{
  param(
      [String[]]$Names,
      [Object[][]]$Data
  )
  $myProps = for($i = 0;; ++$i){
    $Props = [ordered]@{}
    for($j = 0; $j -lt $Data.Length; ++$j){
      if ($i -lt $Data[$j].Length){
        $Props.Add($Names[$j], $Data[$j][$i])
      }
    }
    if (!$Props.get_Count()){
      break
    }
    [PSCustomObject]$Props
  }
  $myProps | Format-Table
}

Поскольку проблема связана исключительно с отображением, лучше решать ее на этом уровне, а не переписывать, какие данные выводит функция: Write-ArrayToTable "Label1","Label2" $arr1,$arr2 | Out-Host будет делать. Это вызывает синхронный вывод на дисплей и, таким образом, решает исходную проблему, которая заключается в асинхронном выводе на дисплей, который вы получаете с неявно отформатированным выводом в виде таблицы, в результате чего приглашение Read-Host неожиданно отображается первым.

mklement0 28.10.2022 19:56

Другие вопросы по теме