Я думаю, что не совсем понимаю ваш вариант использования, но главное отличие между concatMap
и concat
состоит в том, что concatMap
принимает в качестве параметра функцию, которая вызывается для каждого элемента из его источника и которая возвращает внутренняя наблюдаемая (она отображает каждый элемент из своего источника в наблюдаемую). concatMap
затем вызывает свой обратный вызов только тогда, когда завершаются предыдущие внутренние Observables.
С другой стороны concat
просто принимает список наблюдаемых, которые подписываются на них один за другим, когда завершается предыдущая наблюдаемая.
Так что в вашем случае первый пример просто «отображает» FAKE_LOGIN_AUTHENTICATING
на FAKE_LOGIN_SUCCESS
.
Во втором примере внутренний блок эквивалентен этому:
concat(
of({ type: 'FAKE_LOGIN_AUTHENTICATING' }),
of({ type: 'FAKE_LOGIN_SUCCESS', payload: { userId: 'user-a', userData: {}}}).pipe(
delay(2000),
)
)
Таким образом, он сначала подписывается на of({ type: 'FAKE_LOGIN_AUTHENTICATING' })
, который генерирует и завершает немедленно, а затем подписывается на of({ type: 'FAKE_LOGIN_SUCCESS'...)
, который генерирует также затем завершает.
Сам объект DataView используется для циклического перебора строк DataView.
Строки DataView представлены объектом DataRowView . Свойство DataRowView.Row обеспечивает доступ к исходной строке DataTable.
C #
foreach (DataRowView rowView in dataView)
{
DataRow row = rowView.Row;
// Do something //
}
VB.NET
For Each rowView As DataRowView in dataView
Dim row As DataRow = rowView.Row
' Do something '
Next
Можно выполнить итерации DefaultView
как следующий код Indexer
:
DataTable dt = new DataTable();
// add some rows to your table
// ...
dt.DefaultView.Sort = "OneColumnName ASC"; // For example
for (int i = 0; i < dt.Rows.Count; i++)
{
DataRow oRow = dt.DefaultView[i].Row;
// Do your stuff with oRow
// ...
}