Команды PowerShell не работают [дубликат]

Есть еще одно решение, если вы не используете собственные обещания, но Bluebird.

Вы также можете попробовать использовать Promise.map () , смешивая array.map и Promise.all

. В вашем случае:

  var arr = [1,2,3,4,5];

  var results: number[] = await Promise.map(arr, async (item): Promise => {
    await callAsynchronousOperation(item);
    return item + 1;
  });

8
задан PetSerAl 18 January 2016 в 17:00
поделиться

2 ответа

Format-Table не имеет ничего общего с тем, что я просто попробую сделать следующее в PowerSell V 4.0 и PowerShel V5.0, и проблема может быть воспроизведена:

Get-Process |Select-Object -Property name ; pause

арка поворота:

Get-Process |Select-Object -Property Name  |%{Write-host $_.name};pause

Здесь снова выполняется пауза:

Get-Process |%{$_.name | Set-Content 'c:\temp\test.txt';$_} |Select-Object -Property Name  ;pause

Но не здесь

Get-Process |%{$_.name | Set-Content 'c:\temp\test.txt';Start-Sleep -Milliseconds 1;$_} |Select-Object
-Property Name  ;pause

Для меня в PowerShell V5.0 все работает, как если бы хост не нужен в инструкциях, которые конвейерны, тогда эти инструкции запускаются асинхронно.

Мне бы хотелось, чтобы люди, как @Keith Hill, смотрели на это поведение.

1
ответ дан JPBlanc 21 August 2018 в 01:38
поделиться
  • 1
    Все неявно передаются по каналу Out-Default, поэтому ваш первый код эквивалентен .{Get-Process |Select-Object -Property name ; pause}|Out-Default. И Out-Default решили использовать Format-Table для форматирования вывода. Так что на самом деле у вас есть .{Get-Process |Select-Object -Property name ; pause}|Format-Table. Если вы измените Format-Table на Format-List или явно задали ширину столбца Format-Table @{e='Name';w=50}, тогда после выхода будет вызываться pause. Если вы добавляете синхронизацию для каждого выходного объекта, то вы увидите, что запуск выводится через интервал 300 миллисекунд. – PetSerAl 18 January 2016 в 08:17
  • 2
    .{1..20|ForEach-Object {$SW=[Diagnostics.Stopwatch]::StartNew()}{Write-Host "Before writing '$_' ($($SW.ElapsedMilliseconds))";[PSCustomObject]@{Property=$_};Write-Host "After writing '$_' ($($SW.ElapsedMilliseconds))";Start-Sleep -Milliseconds 20}}|Format-Table – PetSerAl 18 January 2016 в 08:18
  • 3
    Команда в целом привязана к одному экземпляру Out-Default. Вы можете видеть это, переопределяя Out-Default. function Out-Default{begin{Write-Host B}process{Write-Host P}end{Write-Host E}}. С помощью этой команды 1,2;3,4 вы увидите B, P, P, P, P, E. Так что это .{1,2;3,4}|Out-Default, а не 1,2|Out-Default;3,4|Out-Default. И я не говорю, что сборка Out-Default всегда предпочитает использовать Format-Table. Я только говорю, что вы выбираете Format-Table для вашего вывода (пользовательский объект с единственным свойством без форматирования, определенного в файлах формата). – PetSerAl 18 January 2016 в 09:27
  • 4
    .{Get-Process |Select-Object -Property Name |Format-Table;pause}|Out-Default: Format-Table применил только к этому Get-Process |Select-Object -Property Name. Когда вызывается конечный блок Format-Table (и это явно происходит перед следующей командой pause), он выводит любые удерживающие объекты. Out-Default см. объект форматирования и не используйте для них форматирование добавок и не печатайте их на консоли без задержки. – PetSerAl 18 January 2016 в 09:41
  • 5
    .{Get-Process |Select-Object -Property Name ;pause}|Out-Default: Get-Process |Select-Object -Property Name вывод пользовательских объектов с единственным свойством без форматирования, определенных в файлах формата, а Out-Default - использование Format-Table. Format-Table удерживайте объекты в течение 300 миллисекунд, чтобы определить ширину столбца. Get-Process|Select-Object -Property Name;pause;[PSCustomObject]@{Name='On that object column width for Name desided'};[PSCustomObject]@{Name='That string will be cutted as it does not fit column width for Name column'} – PetSerAl 18 January 2016 в 09:52

Что вы видите, это последствия новой функции PowerShell v5. Format-Table теперь собирают ввод в течение 300 миллисекунд, чтобы найти лучшую ширину столбца. Он работает таким образом, даже если вы явно указали -AutoSize:$false.

Когда вы вводите команду в командной строке, эта команда неявно передается в один экземпляр команды Out-Default. Затем команда Out-Default определяет, как форматировать объекты и печатать их на хосте (консоли) PowerShell. Таким образом, даже если вы не используете Format-Table непосредственно в своем коде, это не означает, что у вас нет Format-Table в вашем конвейере. Out-Default может решить форматировать объекты как таблицу и использовать Format-Table внутренне.

Пользовательские объекты с четырьмя или менее свойствами и без специального форматирования, определенные для них в файлах формата, отформатированы как таблица. Используя Select-Object с двумя свойствами, вы создаете именно эти объекты.

Конвейер PowerShell является однопоточным. Это означает, что Format-Table не может просто выводить все собранные объекты, когда прошло интервал в 300 миллисекунд. Format-Table должны ждать, пока вы не нанесете на него следующий элемент (вызванный процесс) или конец сообщенного конвейера (вызванный конечный блок).

PS> Get-NetAdapter | Select-Object Name,Status
>>> Pause
>>> [PSCustomObject]@{Name='Some long name';Status='Some long status'} #1
>>> Pause
>>> [PSCustomObject]@{Name='Even longer name';Status='Even longer status'}
>>> Pause

Press Enter to continue...:
Name           Status
----           ------
Ethernet       Up
Some long name Some long status
Press Enter to continue...:
Even longer... Even longer s...
Press Enter to continue...:


PS>

Неявный Format-Table ничего не печатает (строго говоря он печатает пустую строку) перед первым Pause, потому что он все еще ждет больше входных объектов (еще 300 миллисекунд), чтобы определить ширину столбца. Когда первый объект (# 1) приходит через интервал 300 миллисекунд (при условии, что вы не должны нажимать клавишу Enter), тогда Format-Table выбирает ширину столбца и печатает все собранные объекты. Любые другие объекты будут напечатаны без задержки, но они больше не могут влиять на ширину столбца. Если значение является большим для столбца, оно будет усечено.

PS> Get-NetAdapter | Select-Object Name,Status | Format-Table
>>> Pause

Name     Status
----     ------
Ethernet Up


Press Enter to continue...:
PS>

С помощью этого кода до Format-Table будет выполнен конечный блок явного Format-Table. В конце блока Format-Table известно, что он уже получил все входные данные, поэтому он может выбирать ширину столбца и сразу выводить все собранные объекты. Неявные Out-Default видят, что объекты форматирования из выхода Format-Table и Out-Default знают, что им не требуется форматирование добавок и их печать на хосте (консоли) сразу же. Итак, вся таблица была напечатана до Pause.

Обратите внимание на разницу в размещении конца метки таблицы (две пустые строки). В первом примере он помещается после последнего Pause. Это потому, что неявный Format-Table все еще активен и все еще ждет, что вы передаете ему дополнительный объект. Только когда ваша команда полностью завершена Format-Table, подтвердите завершение ввода и вывода конца таблицы. Во втором примере явная Format-Table завершается до Pause, поэтому вся таблица (включая конец таблицы) печатается перед командой Pause.

Разница в размещении конца метки таблицы может быть заметил и предыдущие версии PowerShell.

6
ответ дан PetSerAl 21 August 2018 в 01:38
поделиться
  • 1
    Извините, но то, что я не понимаю в вашей демонстрации, - это почему с явным форматированием? – JPBlanc 19 January 2016 в 05:33
  • 2
    @JPBlanc Я добавляю эту информацию в свой ответ. – PetSerAl 19 January 2016 в 08:19
Другие вопросы по тегам:

Похожие вопросы: