Ребята я конечно понимаю что вы сейчас все говорите что задачи были простыми и для уровня джуна. Но решать такие задачи когда ты волнуешся и у тебя ограниченное время и решать задачи когда ты проста смотришь все это с дивана, это совсем другое. Я гарантирию что люди которые говорили что это задача была простой, в реальном интервью они даже не смогли бы решить даже вторую задачу)))
про гонку имелось ввиду из доки реакт, один из вариантов "Обратите внимание на переменную ignore, которая инициализируется значением false и устанавливается в значение true во время очистки. Это гарантирует, что ваш код не будет страдать от «состояний гонки»: ответы сети могут приходить в другом порядке, чем вы их отправили." export default function Page() { const [person, setPerson] = useState('Alice'); const [bio, setBio] = useState(null); useEffect(() => { let ignore = false; setBio(null); fetchBio(person).then(result => { if (!ignore) { setBio(result); } }); return () => { ignore = true; }; }, [person]);
данный вариант не решает проблему с гонкой запросов. Он решает только проблему с резолвом запроса на компоненте, который уже размонтировался. Но при выборе пользователя компонент с биографией просто перерендеривается, `() => ignore = true` не сработает в этом случае. export default function Page() { const [person, setPerson] = useState('Alice'); const [bio, setBio] = useState(null); const abortRef = useRef(null); if (abortRef.current) { abortRef.current.abort(); abortRef.current = null; } useEffect(() => { const abortCtrl = abortRef.current = new AbortController(); fetchBio(person, { signal: abortCtrl.signal }).then(result => { setBio(result); }) .catch(e => {}); return () => { abortCtrl.abort() }; }, [person]); Вот одно из решений с использованием API браузера. fetch-запросы будут отменяться и при размонтировании, и при выборе нового пользователя.
@@Boortwint первый пример сработает, все запросы выполнятся, но запишется только результат последнего в доке по реакту - "Additionally, if a component renders multiple times (as they typically do), the previous effect is cleaned up before executing the next effect."
Интервьювер спрашивает правильные вопросы. Они в основном не про Реакт, а про опыт решения проблем. Увидительно, что автор, например, ни разу не встречал ситуацию с тем, что два одинаковых запроса могут вернуться в неопределённом порядке. Это вообще в любой асинхронной среде случается, что мобилки, что браузер.
Привет, Кирилл! Учусь сейчас на первом курсе в строительного после медицинского колледжа и твои видео-уроки это просто какое-то спасение! Спасибо тебе большое за них🙏🏻 В своих старых видео ты говорил о том, что можешь помочь на контрольной по высшей математике за денежку. Я хотела бы узнать у тебя, занимаешься ли ты на данный момент таким или может можешь кого-нибудь посоветовать?
че там в итоге на 43:22 какой ответ правильный? мне пришло в голову что надо из юзЭффекта сделать return () => res.reject() чтоб при размонтировке промис не крутился. Верно?
AbortController позволяет отменять запросы, не допуская таких ситуаций. Его прокидывают в запрос и в нужный момент вызывают abort (обычно при unmount или же при повторном запросе). В данном случае можно хранить этот controller в ref, таким образом избегая ререндеров ненужных.
Если тебе дают такие задачи то вакансия на Джуна скорее всего, у мидла+ такое стыдно спрашивать. Просто задачи в вакууме, ни для чего и никак не влияющие на работу
Возможно ты дал в конце видео ответ, но как я понял в задаче с Твитттером интервьюер просил тебя просто добавить ещё один жизненный цикл компонента componentWillUnmount, вернув fetch функцию в useEffect
Когда ты говоришь про максимальную зп, не имеет уже значения фронт ты или бек или еще кто, ты уже и жнец и на дуде игрец, тебе без разницы на чем писать и что делать, имхо, а так макс что я лично видел для фронта в топах 300-350к, если не тимлид, на руки, без премий А средняя мб 150-180к, сильно зависит от компании и их грейда, а не даже от твоего скила, где то сеньор сидит на 200к, а где-то мидл, такое повсеместно, имхо опять же ну и мульон это не зп программиста в рф на компанию из рф, в России, это уже ближе к тимлидам-руководителям, да и то, что частный случай, где столько платят гошникам?
21:53 "строчка кажется странной - переменной присваиваем функцию, никогда не видел такого" (с) кандидат на Senior React, 2023 год. В принципе на этом собеседование можно было закончить =) Ответ был дан правильный, но сам факт удивления и неуверенности в ответе не оставляет сомнения.
1:01:00 - поставить счетчик? разве нельзя было запихивать в массив просто с помощью push? Со счетчиком код нагруженнее + лишняя переменная. Спасибо за видео
Возможно, моя экспертиза не отражает суть вещей, но это даже и близко не уровень мидла. Я решил эту задачу вообще не имея опыта с реактом в продакшене. У меня за плечами только лишь самостоятельное изучение этой библиотеки и прохождение курса в далёком 2018 году, после чего я возвращался к React для своих пет-проектов время от времени.
тут речь больше про решение для бизнес задачи. Условно сделать сейчас или отправить джуна на изучение воркеров и только после этого приступить к задаче.
@@ТёмаКоролёв-к6ф что там изучать то ))) На mdn раздел про воркеры читается минут за 10. Примеров там тьма. Главное по красоте освободить память, больше там никакой магии я не припомню )
Тут все просто, если ценишь свое время - идешь в синьора, потом поднабравшись опыта в разных задачах и ситуациях - в лида. Не всегда имеет смысл горбатиться 1 год джуном и 3 миддлом, если твои знания достаточно обширны
Перерендер-то будет. Только вот fetch запрос с новым именем не отправится. Будут всегда отображаться данные с пользователем, с именем которого компонент примонтировался.
Нифига не понял как на видео решалась задача, но поставил на паузу и попробовал решить сам, вышло 35 минут и такое решение: function done(text) { return text; } var a = function(done) { setTimeout(() => { done("result a") }, 300); } var b = function(done) { setTimeout(() => { done("result b") }, 200); } async function parallel (funcArr, callback){ const p1 = new Promise(resolve => a(resolve)) const p2 = new Promise(resolve => b(resolve)) const [...funcs] = arguments[0] const promArr = [] funcs.forEach(el => { promArr.push(new Promise(resolve => el(resolve))) }); const data = await Promise.all(promArr).then((res) => res) callback(data) } parallel ([a,b], (res) => { console.log(res) }) p.s сам не работаю как разраб на сейчас, к сожалению, но какие то рабочие задачи решаю
const parallel = (funs, callback) => { Promise.all(funs.map(f => new Promise(r => f(r)))).then(callback) }; Но по задаче нужно создать свой Promise.all: const parallel = (funcArray, doneAll) => { let results = []; funcArray.map(f => new Promise(resolve => f(resolve)).then(r => results.push(r))); new Promise(resolve => { const keyInterval = setInterval(() => { if (results.length === funcArray.length) { clearInterval(keyInterval); resolve(results); } }, 0); }).then(doneAll); } Для подготовки лучше использовать bigfrontend.dev
@@RomanTchekashov огонь! Только Promise.all работает выдаёт слегка другой результат. Он возвращает массив с результатами в том же порядке, в котором находились промисы или другие данные в передаваемом в Promise.all массиве. В задаче результаты выводятся в соответствии с порядком резолва промиса Мучить бедный стек контекстов исполнения интервалом в 0 секунд - не самое лучшее решение. Можно сделать проще. function parallel(funcArray, doneAll) { const results = []; funcArray.forEach((func, index, arr) => { new Promise((resolve) => func(resolve)) .then(result => { results.push(result); if (results.length === arr.length) { doneAll(results); } }) }) }
Если ты претендуешь на позицию старшего разработчика, то на мой взгляд нужно более грамотно объяснять технические вопросы, без слов-паразитов и адаптаций. Иначе выглядит колхозно
У последней задачи решение неверное. Как собеседующий это не увидел? При чем собеседующий даже акцент сделал на порядке вывода на 44:12.Там же функции асинхронно вызываются через таймаут. В этом мне кажется и есть весь смысл задачи, чтобы вызывать их последовательно. При решении данном в интервью, будет резульлтат "result b, result a". Правда в таком случае название функции не совсем корректное. Верное решение: function parallel(funcArray, doneAll) { if (!funcArray.length) { return } if (funcArray.length === 1) { return new Promise((res) => funcArray[0]((arg) => res(arg))).then((arg) => doneAll(arg) ) } const first = funcArray[0] const rest = funcArray.slice(1) return rest .reduce((prev, current) => { return prev.then( (prevArg) => new Promise((res) => current((arg) => res(prevArg + ', ' + arg))) ) }, new Promise((res) => first((arg) => res(arg)))) .then((arg) => doneAll(arg)) }
А в чем резон проверять на наличие одного промиса? Не совсем понял. У меня вышло немного по-другому вышло async function parallel(array, doneALL) { if (!array.length) { return; } const result = []; array.forEach((element) => { result.push(new Promise(element)); }); const res = await Promise.all(result); return doneALL(res); } const a = function (done) { setTimeout(function () { done("result a"); }, 300); }; const b = function (done) { setTimeout(function () { done("result b"); }, 200); }; parallel([a, b], function (res) { console.log(res); });