1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/aim-leo-async-multiple

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
Внести вклад в разработку кода
Синхронизировать код
Отмена
Подсказка: Поскольку Git не поддерживает пустые директории, создание директории приведёт к созданию пустого файла .keep.
Loading...
README.md

Асинхронная-Множественная

Лёгкая библиотека выполнения асинхронной очереди!

Установка

Используя npm:

$ npm install async-multiple

Пример

map

import { map } from 'async-multiple'
const задача = [1, 2, 3, 4, 5]
map({
  задача,
  обработчик: async (элемент) => {
    // Вы также можете использовать другие асинхронные функции, такие как fetch или ajax
    await this.sleep(1000)
    if (элемент === 3) {
      return Promise.reject(new Error('Не 3!'))
    }
    return Promise.resolve(элемент * элемент)
  }
})
.then(результат => {
  console.log(результат)
})

// Результат
[
  { порядок: 0, вход: 1, выход: 1, ошибка: null },
  { порядок: 1, вход: 2, выход: 4, ошибка: null },
  { порядок: 2,
    вход: 3,
    выход: null,
    ошибка: 'Не 3!',   // Объект ошибки
  },
  { порядок: 3, вход: 4, выход: 16, ошибка: null },
  { порядок: 4, вход: 5, выход: 25, ошибка: null }
]

each

import { each } from 'async-multiple'
each({
  задача: [
    async () => {
      return Promise.resolve(1)
    },
    async () => {
      return Promise.resolve(2)
    },
    async () => {
      return Promise.resolve(3)
    },
    async () => {
      return Promise.reject(new Error('Не 4'))
    },
    async () => {
      return Promise.resolve(5)
    },
  ],
})
.then(результат => {
  console.log(результат.toArray())
})

// Результат
[
  { порядок: 0, выход: 1, ошибка: null },
  { порядок: 1, выход: 2, ошибка: null },
  { порядок: 2, выход: 3, ошибка: null },
  { порядок: 3,
    выход: null,
    ошибка: 'Не 4'
  },
  { порядок: 5, выход: 5, ошибка: null }
]

API

map(конфиг)

Цикл задач можно создать путём передачи соответствующего конфига в map.

задача##### Обязательный: Да Тип: Массив

Пример
map({
  задача: [1, 2, 3, 4, 5]
})

map({
  задача: ['файл1', 'файл2', 'файл3', 'файл4', 'файл5']
})

Обработчик

Обязательный: Да Тип: Функция
Обратный вызов возвращает: Промис
ВАЖНО

Когда обработчик не возвращает промис, но вместо этого возвращает значение, такое как число или строку, это значение будет обёрнуто в Promise.resolve. Если нет возврата, задача останавливается на этом шаге!

Параметры обратного вызова: (вход, шаг, отменаЗадачи)
Вход: Данные из массива задач
Шаг: Шаг задачи
ОтменаЗадачи: Глобальная функция отмены, если она вызвана, задача останавливается на этом шаге, то есть вы можете отменять задачу до каждого шага
Пример
// Возвращает значение
map({
  задача: [1, 2, 3, 4, 5],
  обработчик: вход => вход
})

// То же самое что
map({
  задача: [1, 2, 3, 4, 5],
  обработчик: вход => Promise.resolve(вход)
})

// Обработка ошибки
map({
  задача: [1, 2, 3, 4, 5],
  обработчик: вход => {
    if (вход === 3) {
      return Promise.reject(new Error('Не 3, завершено с ошибкой!'))
    }
    return Promise.resolve(вход)
  }
})

// Использование async/await
map({
  задача: [1, 2, 3, 4, 5],
  обработчик: async вход => {
    await sleep(1000)
    return Promise.resolve(вход)
  }
})

rejectOnError

Обязательный: Нет Тип: Boolean Значение по умолчанию: False
Установка значения True: Задача будет прекращена при получении отклонения
Пример```js

map({ task: [1, 2, 3, 4, 5], handle: input => { if (input === 3) { return Promise.reject(new Error('not 3!')) } return Promise.resolve(input) }, rejectOnError: true }) // результат [ { порядок: 0, вход: 1, выход: 1, ошибка: null }, { порядок: 1, вход: 2, выход: 4, ошибка: null }, { порядок: 2, вход: 3, выход: null, ошибка: 'not 3!', // object error } ]


Корректировка:

```js
map({
  task: [1, 2, 3, 4, 5],
  handle: input => {
    if (input === 3) {
      return Promise.reject(new Error('not 3!'))
    }
    return Promise.resolve(input)
  },
  rejectOnError: true
})
// результат
[
  { порядок: 0, вход: 1, выход: 1, ошибка: null },
  { порядок: 1, вход: 2, выход: 4, ошибка: null },
  { порядок: 2,
    вход: 3,
    выход: null,
    ошибка: 'не 3!',   // объект ошибки
  }
]
```#### случайный_шаг

##### обязательный: нет тип: boolean значение по умолчанию: false
##### установка значения true: случайный вызов задачи

##### пример

```js
map({
  task: [1, 2, 3, 4, 5],
  handle: async (элемент) => {
    return Promise.resolve(элемент)
  },
  случайный_шаг: true,
  handleStart: ({ шаг, вход }) => {
    console.log(`начало обработки на шаге ${шаг}, вход: ${вход}`)
  },
})
.then(результат => {
  console.log(результат.toArray())
})
// результат
начало обработки на шаге 0, вход: 2 
начало обработки на шаге 1, вход: 5 
начало обработки на шаге 2, вход: 1 
начало обработки на шаге 3, вход: 3 
начало обработки на шаге 4, вход: 4 
[
  { порядок: 0, вход: 1, выход: 1, ошибка: null },
  { порядок: 1, вход: 2, выход: 2, ошибка: null },
  { порядок: 2, вход: 3, выход: 3, ошибка: null },
  { порядок: 3, вход: 4, выход: 4, ошибка: null },
  { порядок: 4, вход: 5, выход: 5, ошибка: null }
]

шаг_между

обязательный: нет тип: [число, массив] значение по умолчанию: 0
пример
// каждая задача будет ждать 1000 миллисекунд перед выполнением
map({
  task: [1, 2, 3, 4, 5],
  handle: async (элемент) => {
    return Promise.resolve(элемент)
  },
  шаг_между: 1000
})

// каждая задача будет ждать 500~2000 миллисекунд перед выполнением
map({
  task: [1, 2, 3, 4, 5],
  handle: async (элемент) => {
    return Promise.resolve(элемент)
  },
  шаг_между: [500, 2000]
})

timeout_шага

обязательный: нет тип: число значение по умолчанию: неопределено
пример```js

// Если время выполнения шага больше stepTimeout, этот шаг будет отклонён, затем вызовется следующий шаг, // и получен будет ошибочный ответ с таймаутом. map({ task: [1, 2, 3, 4, 5], handle: someFunction, // асинхронная функция, например fetch или readFile stepTimeout: 1000 })


##### Обязательный: Нет Тип: Число Значение по умолчанию: 0

##### Пример

```js
// Если установлено, при получении отказа, обработчик будет повторно вызван в следующем шаге
// Если количество вызовов превышает errorRetry, будет получен ошибочный результат, затем вызван следующий шаг
const task = [1, 2, 3, 4, 5];
let flag = false;
map({
  task,
  handle: async (item) => {
    if (item === 3) {
      if (flag === false) {
        flag = true;
        return Promise.reject(new Error('Флаг равен false'));
      }
      return Promise.resolve(item);
    }
    return Promise.resolve(item);
  },
  errorRetry: 3,
  handleStart: ({ step, input, isRetry }) => {
    console.log(`Начало обработки на шаге ${step}, входные данные: ${input} ${isRetry ? '[Повтор]' : ''}`);
  },
});
.then(result => {
  console.log(result.toArray());
});

maxSuccessCount

Обязательный: Нет Тип: Число Значение по умолчанию: Неопределено
Пример
// Если установлено, при получении достаточного количества успешных результатов, задача будет завершена
map({
  task: [1, 2, 3, 4, 5],
  handle: someFunction,  // Асинхронная функция, например fetch или readFile
  maxSuccessCount: 3
});

// Результат
начало обработки на шаге 0, входные данные: 1 
начало обработки на шаге 1, входные данные: 2 
начало обработки на шаге 2, входные данные: 3 
[async-multiple MESSAGE]: Достаточно успешных результатов, задача завершена!
[
  { порядок: 0, входные данные: 1, выходные данные: 1, ошибка: null },
  { порядок: 1, входные данные: 2, выходные данные: 2, ошибка: null },
  { порядок: 2, входные данные: 3, выходные данные: 3, ошибка: null }
]
```#### showProgress

##### Обязательный: Нет Тип: Логический Значение по умолчанию: False

##### Пример

```js
// Если установлено, при получении достаточного количества успешных результатов, задача будет завершена
const task = [1, 2, 3, 4, 5];
map({
  task,
  handle: async (item) => {
    return Promise.resolve(item);
  },
  showProgress: true
});
then(result => {
  console.log(result.toArray());
});

// result [TASK_csv1LTmw] Все: 5 Завершено: 1 Прогресс: 20.00% [TASK_csv1LTmw] Все: 5 Завершено: 2 Прогресс: 40.00% [TASK_csv1LTmw] Все: 5 Завершено: 3 Прогресс: 60.00% [TASK_csv1LTmw] Все: 5 Завершено: 4 Прогресс: 80.00% [TASK_csv1LTmw] Все: 5 Завершено: 5 Прогресс: 100.00% [ { order: 0, input: 1, output: 1, error: null }, { order: 1, input: 2, output: 2, error: null }, { order: 2, input: 3, output: 3, error: null }, { order: 3, input: 4, output: 4, error: null }, { order: 4, input: 5, output: 5, error: null } ]


##### Обязательный: Нет Тип: Строка Значение по умолчанию: Неопределено

##### Пример

```js
// Если установлено, задача будет отменена при получении достаточного количества решений и остановлена на следующем шаге
const task = [1, 2, 3, 4, 5];
map({
  task,
  handle: async (item) => {
    return Promise.resolve(item);
  },
  showProgress: true,
  alias: 'loop task'
});
then(result => {
  console.log(result.toArray());
});// результат
[ loop task ] всего: 5 завершено: 1 прогресс: 20.00%
[ loop task ] всего: 5 завершено: 2 прогресс: 40.00%
[ loop task ] всего: 5 завершено: 3 прогресс: 60.00%
[ loop task ] всего: 5 завершено: 4 прогресс: 80.00%
[ loop task ] всего: 5 завершено: 5 прогресс: 100.00%
[
  { порядок: 0, входной_данные: 1, выходной_данные: 1, ошибка: null },
  { порядок: 1, входной_данные: 2, выходной_данные: 2, ошибка: null },
  { порядок: 2, входной_данные: 3, выходной_данные: 3, ошибка: null },
  { порядок: 3, входной_данные: 4, выходной_данные: 4, ошибка: null },
  { порядок: 4, входной_данные: 5, выходной_данные: 5, ошибка: null }
]
```#### handleStart | handleEnd

##### Обязательный: Нет Тип: Функция Значение по умолчанию: Неопределено

##### Пример

```js
const task = [1, 2, 3, 4, 5];
map({
  task,
  handle: async (item) => {
    return Promise.resolve(item);
  },
  handleStart: ({ step, input, isRetry }) => {
    console.log(`начало обработки на шаге ${step}, входные данные: ${input} ${isRetry ? '[повторение]' : ''}`);
  },
  handleEnd: ({ step, input, isRetry }) => {
    console.log(`конец обработки на шаге ${step}, входные данные: ${input} ${isRetry ? '[повторение]' : ''}`);
  },
});
.then((result) => {
  console.log(result.toArray());
});

// Результат
начало обработки на шаге 0, входные данные: 1 
конец обработки на шаге 0, входные данные: 1 
начало обработки на шаге 1, входные данные: 2 
конец обработки на шаге 1, входные данные: 2 
начало обработки на шаге 2, входные данные: 3 
конец обработки на шаге 2, входные данные: 3 
начало обработки на шаге 3, входные данные: 4 
конец обработки на шаге 3, входные данные: 4 
начало обработки на шаге 4, входные данные: 5 
конец обработки на шаге 4, входные данные: 5 
[
  { порядок: 0, входной_данный: 1, выходной_данный: 1, ошибка: null },
  { порядок: 1, входной_данный: 2, выходной_данный: 2, ошибка: null },
  { порядок: 2, входной_данный: 3, выходной_данный: 3, ошибка: null },
  { порядок: 3, входной_данный: 4, выходной_данный: 4, ошибка: null },
  { порядок: 4, входной_данный: 5, выходной_данный: 5, ошибка: null }
]

Каждый(конфиг)

Все параметры такие же как в map, за исключением task и handle(каждый не имеет этих параметров).#### задача

обязательный: да тип: массив
каждый маска принимает список, содержащий обработчики, которые вы хотите вызвать##### пример
const задача = [
  () => {},  // что делать 1
  () => {},  // что делать 2
  () => {},  // что делать 3
  () => {},  // что делать 4
]
map({
  задача,
})
.then(результат => {
  console.log(результат.toArray())
})

КОНСТРУКТ

Map | Each

пример

import { Map, Each } from 'async-multiple'
const цикл = new Map({
  задача: [1, 2, 3, 4, 5],
  обработчик: s => s,
})
цикл.start().then(
  результат => {
    console.log(результат)
  }
)

const цикл = new Each({
  задача: [
    () => {},  // что делать 1
    () => {},  // что делать 2
    () => {},  // что делать 3
    () => {},  // что делать 4
  ],
})
цикл.start().then(
  результат => {
    console.log(результат)
  }
)

методы

start

вызовите этот метод для запуска задачи, возвращает промис

cancelTask

вызовите этот метод для отмены задачи глобально

Событие

пример

import { Event } from 'async-multiple'
const eventBus = new Event({ debug: true })

eventBus.on('action1', (params) => {
  console.log('action1 called!', params)
}, 5)

eventBus.on('action1', (params) => {
  console.log('action1 called!', params)
}, 5)

setInterval(() => {
  eventBus.emit('action1', '123')
}, 1000)

методы

on
параметры

actionName: название действия, которое вы прослушиваете callback: обратный вызов, параметры — полученные данные callTime: максимальное количество вызовов обратного вызова, если не указано, ограничение отсутствует

примечание

Вы можете зарегистрировать его несколько раз, как показано ниже:```js import { Event } from 'async-multiple'; const eventBus = new Event({ debug: true });

eventBus.on('action1', (params) => { console.log('action1 called! function 1', params); });

eventBus.on('action1', (params) => { console.log('action1 called! function 2', params); });

setInterval(() => { eventBus.emit('action1', '123'); }, 1000);


Каждый обратный вызов будет выполнен

##### one-time
###### параметры
actionName: действие, которое вы прослушиваете
callback: обратный вызов, параметры — полученные данные, может быть вызван один раз

##### emit
###### параметры
actionName: действие, которое вы отправляете
data: данные, которые вы отправляете

## TODO

#### одновременный запуск нескольких задач

## Лицензия (MIT)

Авторское право © 2019 Leo Согласно настоящей лицензии бесплатно предоставляется каждому лицу, получившему копию данного программного обеспечения и связанных с ним документов («Программное обеспечение»), право использовать Программное обеспечение без каких-либо ограничений, включая, но не ограничиваясь правами на использование, копирование, изменение, объединение, публикацию, распространение, предоставление sublicense (подлицензии) и/или продажу копий Программного обеспечения, а также право допускать других лиц к использованию Программного обеспечения при условии соблюдения следующих условий:

Приведённое выше уведомление об авторском праве и это уведомление о разрешении должны присутствовать во всех копиях или значительных частях Программы.
```ПРОГРАММА предоставляется «КАК ЕСТЬ», БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ, ЯВНО ВЫДАВаемых ИЛИ
НЕЯВНО ВЫДАВаемых, ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ ГАРАНТИЯМИ ТОРГОВЛЕНИЯ, ПРИГОДНОСТИ ДЛЯ
ОСОБОЙ ЦЕЛИ И НЕНАРУШЕНИЯ ПРАВ. В НИКАКОМ СЛУЧАЕ АВТОРЫ ИЛИ
владельцы авторских прав НЕ БУДУТ ОТВЕТСТВЕННЫМИ ЗА ЛЮБЫЕ ПРЕТЕНДИРОВАННЫЕ УЩЕРБЫ, УЩЕРБЫ ИЛИ
ДРУГИЕ ОТВЕТСТВЕННОСТИ, НАПРАВЛЕННЫЕ НА ДЕЙСТВИЕ КОНТРАКТА, ДЕЛИКТ ИЛИ ДРУГОЕ,
ВОЗНИКАЮЩИЕ ИЗ, ЧЕРЕЗ ИЛИ В СВЯЗИ С ПРОГРАМОЙ ИЛИ ИСПОЛЬЗОВАНИЕМ ИЛИ ДРУГИМИ
ДЕЙСТВИЯМИ С ПРОГРАММНЫМ ОБЕСПЕЧЕНИЕМ.

---

Перевод:

**ПРОГРАММА предоставляется «КАК ЕСТЬ», БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ, ЯВНО ВЫДАВаемых ИЛИ
НЕЯВНО ВЫДАВаемых, ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ ГАРАНТИЯМИ ТОРГОВЛЕНИЯ, ПРИГОДНОСТИ ДЛЯ
ОСОБОЙ ЦЕЛИ И НЕНАРУШЕНИЯ ПРАВ. В НИКАКОМ СЛУЧАЕ АВТОРЫ ИЛИ
владельцы авторских прав НЕ БУДУТ ОТВЕТСТВЕННЫМИ ЗА ЛЮБЫЕ ПРЕТЕНДИРОВАННЫЕ УЩЕРБЫ, УЩЕРБЫ ИЛИ
ДРУГИЕ ОТВЕТСТВЕННОСТИ, НАПРАВЛЕННЫЕ НА ДЕЙСТВИЕ КОНТРАКТА, ДЕЛИКТ ИЛИ ДРУГОЕ,
ВОЗНИКАЮЩИЕ ИЗ, ЧЕРЕЗ ИЛИ В СВЯЗИ С ПРОГРАМОЙ ИЛИ ИСПОЛЬЗОВАНИЕМ ИЛИ ДРУГИМИ
ДЕЙСТВИЯМИ С ПРОГРАММНЫМ ОБЕСПЕЧЕНИЕМ.**

---

Исправленный вариант:

**ПРОГРАММА предоставляется «КАК ЕСТЬ», БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ, ЯВНО ВЫДАВаемых ИЛИ НЕЯВНО ВЫДАВаемых, ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ ГАРАНТИЯМИ ТОРГОВЛЕНИЯ, ПРИГОДНОСТИ ДЛЯ ОСОБОЙ ЦЕЛИ И НЕНАРУШЕНИЯ ПРАВ. В НИКАКОМ СЛУЧАЕ АВТОРЫ ИЛИ владельцы авторских прав НЕ БУДУТ ОТВЕТСТВЕННЫМИ ЗА ЛЮБЫЕ ПРЕТЕНДИРОВАННЫЕ УЩЕРБЫ, УЩЕРБЫ ИЛИ ДРУГИЕ ОТВЕТСТВЕННОСТИ, НАПРАВЛЕННЫЕ НА ДЕЙСТВИЕ КОНТРАКТА, ДЕЛИКТ ИЛИ ДРУГОЕ, ВОЗНИКАЮЩИЕ ИЗ, ЧЕРЕЗ ИЛИ В СВЯЗИ С ПРОГРАМОЙ ИЛИ ИСПОЛЬЗОВАНИЕМ ИЛИ ДРУГИМИ ДЕЙСТВИЯМИ С ПРОГРАММНЫМ ОБЕСПЕЧЕНИЕМ.**

---

Финальный текст:

**ПРОГРАММА предоставляется «КАК ЕСТЬ», БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ, ЯВНО ВЫДАВаемых ИЛИ НЕЯВНО ВЫДАВаемых, ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ ГАРАНТИЯМИ ТОРГОВЛЕНИЯ, ПРИГОДНОСТИ ДЛЯ ОСОБОЙ ЦЕЛИ И НЕНАРУШЕНИЯ ПРАВ. В НИКАКОМ СЛУЧАЕ АВТОРЫ ИЛИ владельцы авторских прав НЕ БУДУТ ОТВЕТСТВЕННЫМИ ЗА ЛЮБЫЕ ПРЕТЕНДИРОВАННЫЕ УЩЕРБЫ, УЩЕРБЫ ИЛИ ДРУГИЕ ОТВЕТСТВЕННОСТИ, НАПРАВЛЕННЫЕ НА ДЕЙСТВИЕ КОНТРАКТА, ДЕЛИКТ ИЛИ ДРУГОЕ, ВОЗНИКАЮЩИЕ ИЗ, ЧЕРЕЗ ИЛИ В СВЯЗИ С ПРОГРАМОЙ ИЛИ ИСПОЛЬЗОВАНИЕМ ИЛИ ДРУГИМИ ДЕЙСТВИЯМИ С ПРОГРАММНЫМ ОБЕСПЕЧЕНИЕМ.**

---

Итоговый текст:

**ПРОГРАММА предоставляется «КАК ЕСТЬ», БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ, ЯВНО ВЫДАВаемых ИЛИ НЕЯВНО ВЫДАВаемых, ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ ГАРАНТИЯМИ ТОРГОВЛЕНИЯ, ПРИГОДНОСТИ ДЛЯ ОСОБОЙ ЦЕЛИ И НЕНАРУШЕНИЯ ПРАВ. В НИКАКОМ СЛУЧАЕ АВТОРЫ ИЛИ владельцы авторских прав НЕ БУДУТ ОТВЕТСТВЕННЫМИ ЗА ЛЮБЫЕ ПРЕТЕНДИРОВАННЫЕ УЩЕРБЫ, УЩЕРБЫ ИЛИ ДРУГИЕ ОТВЕТСТВЕННОСТИ, НАПРАВЛЕННЫЕ НА ДЕЙСТВИЕ КОНТРАКТА, ДЕЛИКТ ИЛИ ДРУГОЕ, ВОЗНИКАЮЩИЕ ИЗ, ЧЕРЕЗ ИЛИ В СВЯЗИ С ПРОГРАМОЙ ИЛИ ИСПОЛЬЗОВАНИЕМ ИЛИ ДРУГИМИ ДЕЙСТВИЯМИ С ПРОГРАММНЫМ ОБЕСПЕЧЕНИЕМ.**

---

Итоговый текст:

**ПРОГРАММА предоставляется «КАК ЕСТЬ», БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ, ЯВНО ВЫДАВаемых ИЛИ НЕЯВНО ВЫДАВаемых, ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ ГАРАНТИЯМИ ТОРГОВЛЕНИЯ, ПРИГОДНОСТИ ДЛЯ ОСОБОЙ ЦЕЛИ И НЕНАРУШЕНИЯ ПРАВ. В НИКАКОМ СЛУЧАЕ АВТОРЫ ИЛИ владельцы авторских прав НЕ БУДУТ ОТВЕТСТВЕННЫМИ ЗА ЛЮБЫЕ ПРЕТЕНДИРОВАННЫЕ УЩЕРБЫ, УЩЕРБЫ ИЛИ ДРУГИЕ ОТВЕТСТВЕННОСТИ, НАПРАВЛЕННЫЕ НА ДЕЙСТВИЕ КОНТРАКТА, ДЕЛИКТ ИЛИ ДРУГОЕ, ВОЗНИКАЮЩИЕ ИЗ, ЧЕРЕЗ ИЛИ В СВЯЗИ С ПРОГРАМОЙ ИЛИ ИСПОЛЬЗОВАНИЕМ ИЛИ ДРУГИМИ ДЕЙСТВИЯМИ С ПРОГРАММНЫМ ОБЕСПЕЧЕНИЕМ.**

---

Итоговый текст:

**ПРОГРАММА предоставляется «КАК ЕСТЬ», БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ, ЯВНО ВЫДАВаемых ИЛИ НЕЯВНО ВЫДАВаемых, ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ ГАРАНТИЯМИ ТОРГОВЛЕНИЯ, ПРИГОДНОСТИ ДЛЯ ОСОБОЙ ЦЕЛИ И НЕНАРУШЕНИЯ ПРАВ. В НИКАКОМ СЛУЧАЕ АВТОРЫ ИЛИ владельцы авторских прав НЕ БУДУТ ОТВЕТСТВЕННЫМИ ЗА ЛЮБЫЕ ПРЕТЕНДИРОВАННЫЕ УЩЕРБЫ, УЩЕРБЫ ИЛИ ДРУГИЕ ОТВЕТСТВЕННОСТИ, НАПРАВЛЕННЫЕ НА ДЕЙСТВИЕ КОНТРАКТА, ДЕЛИКТ ИЛИ ДРУГОЕ, ВОЗНИКАЮЩИЕ ИЗ, ЧЕРЕЗ ИЛИ В СВЯЗИ С ПРОГРАМОЙ ИЛИ ИСПОЛЬЗОВАНИЕМ ИЛИ ДРУГИМИ ДЕЙСТВИЯМИ С ПРОГРАММНЫМ ОБЕСПЕЧЕНИЕМ.**

---

Итоговый текст:

**ПРОГРАММА предоставляется «КАК ЕСТЬ», БЕЗ КАКИХ-ЛИ

Комментарии ( 0 )

Вы можете оставить комментарий после Вход в систему

Введение

Лёгкая асинхронная библиотека времени выполнения очереди! Развернуть Свернуть
MIT
Отмена

Обновления

Пока нет обновлений

Участники

все

Недавние действия

Загрузить больше
Больше нет результатов для загрузки
1
https://api.gitlife.ru/oschina-mirror/aim-leo-async-multiple.git
git@api.gitlife.ru:oschina-mirror/aim-leo-async-multiple.git
oschina-mirror
aim-leo-async-multiple
aim-leo-async-multiple
master