then()
создаёт ТРИ последовательных микротаска:then()
на том уже отресолвленном промисе, что вернули в C1. И т.к. этот промис уже отресолвлен, сразу же в очередь вставляется следующий микротаск:undefined
, то добавляется всего один микротаск.await
, но потом её оптимизировали в движке V8. А вот про then()
забыли.const log = (value, returnPromise) => () => {
console.log(value);
if (returnPromise) return Promise.resolve();
};
Возвращает функцию, которая обычный console.log() с переданным значением. И если второй аргумент трушный, то вернёт отрезолвленный промис.Promise.resolve()
.then(log('a1'))
.then(log('a2'))
.then(log('a3'))
.then(log('a4'))
.then(log('a5'))
.then(log('a6'))
;
Promise.resolve()
.then(log('b1'))
.then(log('b2'))
.then(log('b3'))
.then(log('b4'))
.then(log('b5'))
.then(log('b6'))
;
Выводит поочередные a1 b1 a2 b2 a3 b3 ...Promise.resolve()
.then(log('a1', true))
.then(log('a2'))
.then(log('a3'))
.then(log('a4'))
.then(log('a5'))
.then(log('a6'))
;
Promise.resolve()
.then(log('b1'))
.then(log('b2'))
.then(log('b3'))
.then(log('b4'))
.then(log('b5'))
.then(log('b6'))
;
a1 b1 b2 b3 a2 b4 a3 b5 a4 b6 a5 a6
then()
выполняется асинхронно. После выполнения очередного, создаётся следующий microtask. Несколько цепочек, как видно из 1-го эксперимента, выполняются параллельно-пошагово, «молнией»."молния"
a1 b1 ; a2 b2 ; a3 b3 ; a4 b4 ; a5 b5 ; a6 b6
с промисом в А1
a1 b1 ; b2 ; b3 a2 ; b4 a3 ; b5 a4 ; b6 a5 ; a6
const output = [];
const makeChain = (key, n = 5, trueStep = false) => {
let p = Promise.resolve();
const arrow = isArrow => isArrow ? '->' : '';
for (let i = 1; i <= n; i++) {
const returnPromise = trueStep === i;
const afterPromise = trueStep === i - 1;
p = p.then(() => {
output.push(`${arrow(afterPromise)}${key}${i}${arrow(returnPromise)}`);
if (returnPromise) return Promise.resolve();
});
}
return p.catch(console.error);
};
const n = 7;
makeChain('a', n, 1),
makeChain('b', n),
makeChain('c', n, 4),
// мАкрозадача выполнится после всех мИкрозадач:
setTimeout(() => console.log(output.join(' ')));
a1-> b1 c1 ; b2 c2 ; b3 c3 ->a2 ; b4 c4-> a3 ; b5 a4 ; b6 a5 ; b7 ->c5 a6 c6 ; a7 c7
Тут всё ещё не вполне мне понятен порядок после возврата промиса из C4.const parent = document.querySelector('.parent');
const toWrapClass = 'child';
const wrapperTag = 'div';
const wrapperClass = 'wrapper';
[...parent.children].reduce((wrapper, n) => {
if (n.classList.contains(toWrapClass)) {
if (!wrapper) {
wrapper = document.createElement(wrapperTag);
wrapper.classList.add(wrapperClass);
n.before(wrapper);
}
wrapper.appendChild(n);
return wrapper;
}
return null;
}, null);
Array.prototype.reduce.call(
parent.querySelectorAll(`:scope > .${toWrapClass}`),
(acc, n, i, a) => (
n.previousElementSibling !== a[i - 1] && acc.push([]),
acc.at(-1).push(n),
acc
),
[]
).forEach(n => {
const wrapper = document.createElement(wrapperTag);
wrapper.className = wrapperClass;
parent.insertBefore(wrapper, n[0]);
wrapper.append(...n);
});
const toWrapSelector = `.${toWrapClass}`;
const wrapperHTML = `<${wrapperTag} class="${wrapperClass}"></${wrapperTag}>`;
for (
let curr = parent.firstElementChild, next = null, prev = null, wrapper = null;
next = curr?.nextElementSibling, curr;
prev = curr, curr = next
) {
if (!curr.matches(toWrapSelector)) {
continue;
}
if (!prev?.matches(toWrapSelector)) {
curr.insertAdjacentHTML('beforebegin', wrapperHTML);
wrapper = curr.previousSibling;
}
wrapper.insertAdjacentElement('beforeend', curr);
}
Выдаёт ошибку:
Traceback (most recent call last):
line 46, in
for m in n.values():
AttributeError: 'int' object has no attribute 'values'
Подскажите как посчитать сумму элементов в данном словаре
def best_function(d):
sum = 0
for v in d.values():
if isinstance(v, dict):
sum += best_function(v)
else:
sum += v
return sum
print(best_function(dct)) # 3906
iptables -t mangle -N SPISOK
iptables -t mangle -A SPISOK -d 10.9.0.0/24 -j RETURN
iptables -t mangle -A SPISOK -d 10.11.0.0/24 -j RETURN
iptables -t mangle -A SPISOK -d 10.14.0.0/24 -j RETURN
iptables -t mangle -A SPISOK -j MARK --set-mark 4
iptables -t mangle -A PREROUTING -i enp1s0 -s 10.8.0.0/24 -j SPISOK
import subprocess
from time import sleep
class CameraMonitor:
def __init__(self):
self.IP12 = '192.168.0.100'
self.IP13 = '192.168.0.101'
self.RODOS12 = '192.168.1.100'
self.RODOS13 = '192.168.1.101'
self.fail_count = {'Купол 12': 0, 'Купол 13': 0}
self.reboot_count = {'Купол 12': 0, 'Купол 13': 0}
def ping_camera(self, ip):
cmd = f'ping {ip} -n 1 -w 100'
response = subprocess.call(cmd, stdout=subprocess.DEVNULL)
return response == 0
def cameras_checker(self):
r_dict = {'Купол 12': self.IP12, 'Купол 13': self.IP13}
while True:
for camera, ip in r_dict.items():
if self.ping_camera(ip):
print(f'Camera {camera} - OK')
self.fail_count[camera] = 0
else:
self.fail_count[camera] += 1
print(f'Camera {camera} - Died')
if self.fail_count[camera] >= 5:
self.cameras_reboot(camera)
sleep(5)
def cameras_reboot(self, camera):
if camera == 'Купол 12':
ip = self.RODOS12
else:
ip = self.RODOS13
self.reboot_count[camera] += 1
print(f'Rebooting {camera} at IP {ip}')
def info(self):
for camera, count in self.reboot_count.items():
print(f'Перезагрузок {camera}: {count}')
if __name__ == "__main__":
monitor = CameraMonitor()
monitor.cameras_checker()
BytesIO
. def get_contact(ids):
for id in ids:
template = f'https://etender.gov.az/api/events/{id}/contact-persons'
try:
response = requests.get(template, timeout=20)
if response.status_code == 200:
data_list = response.json()
for data in data_list:
main_data['Full_name'].append(data.get('fullName', 'None') if data.get('fullName') else 'None')
main_data['Contact'].append(data.get('contact', 'None') if data.get('contact') else 'None')
main_data['Position'].append(data.get('position', 'None') if data.get('position') else 'None')
main_data['Phone_number'].append(data.get('phoneNumber', 'None') if data.get('phoneNumber') else 'None')
else:
main_data['Full_name'].append('None')
main_data['Contact'].append('None')
main_data['Position'].append('None')
main_data['Phone_number'].append('None')
except requests.Timeout:
main_data['Full_name'].append('None')
main_data['Contact'].append('None')
main_data['Position'].append('None')
main_data['Phone_number'].append('None')
main_data = []
...
def get_contact(ids):
for id in ids:
current_data = {'Full_name': 'None', 'Contact': 'None', 'Position': 'None', 'Phone_number': 'None'}
template = f'https://etender.gov.az/api/events/{id}/contact-persons'
try:
response = requests.get(template, timeout=20)
if response.status_code == 200:
data_list = response.json()
for (elem_to, elem_from) in [
('Full_name', 'fullName'),
('Contact', 'contact'),
('Position', 'position'),
('Phone_number', 'phoneNumber')
]:
current_data[elem_to] = data.get(elem_from, 'None')
except requests.Timeout:
pass
main_data.append(current_data)