JS Как привязать функцию на выполнение после обработки другой функции?
Есть необходимость выполнить функцию, после выполнения первой функции, но когда первая будет завершена(и будет ли), отследить сложно. Приведу простой пример что б объяснить сумбур вопроса.
/// WE CAN'T change this elements
const btn = document.getElementById("btn_push");
let sendData = (timeFunc) => { console.log(`Function DONE! It took ${timeFunc} sec`)};
let randomInteger = (min, max) => {
let rand = min - 0.5 + Math.random() * (max - min + 1);
return Math.round(rand);
}
btn.addEventListener("click", function(){
const time = randomInteger(1000, 4000);
setTimeout(sendData(time), time);
});
/// OWN elements
let secondFunction = () => { console.log(`This function done after server get data`)};
Предположим имеется функция отправляющая данные на сервер sendData() по нажатию на кнопку. Сколько она будет выполняться (проводить валидации, общаться с другими API и тд.) нам не известно. Нам известно только её название, и то, что выполнение повешено на клик. Вопрос, как выполнить secondFunction() по завершению выполнения первой функции? *Вторая функция может вызываться совершенно с другого js файла этого же html документа. Возможно ли это как-то отловить, что она завершила действие?
PS Если б это всё было в одном js и можно б было переписать вызов первой функции, то делалось бы через Promise, но этого нету.
Ответы (3 шт):
Вы можете использовать метод setTimeout для запуска функции secondFunction после выполнения функции sendData. Вы можете передать функцию sendData в качестве аргумента в setTimeout, а затем в теле функции sendData вызвать secondFunction.
btn.addEventListener("click", function(){
const time = randomInteger(1000, 4000);
setTimeout(() => {
sendData(time);
secondFunction();
}, time);
});
Так же Вы можете использовать события, которые генерирует sendData(Event), и подписать secondFunction на это событие. Таким образом, secondFunction будет выполнятся только после того, как sendData генерирует событие.
document.addEventListener('sendDataEvent', secondFunction);
let sendData = (timeFunc) => {
console.log(`Function DONE! It took ${timeFunc} sec`);
document.dispatchEvent(new Event('sendDataEvent'));
};
Почему бы не переписать функцию?
const oldFunc = btn.onclick;
btn.onclick = function(e) {
const data = oldFunc(e);
sencodFunction();
return data;
//или
setTimeout(sencodFunction, 200)
return oldFunc(e);
}
let sendData = (timeFunc) => {...};как выполнить secondFunction() по завершению выполнения первой функции?
Если sendData задана именно т.о. - можно использовать прокси объект и "подменить ее".
Если функция асинхронная - код будет выглядеть немного иначе. Но суть будет та же.
Если функция объявлена как const sendData = (timeFunc) => {...} - использование прокси не прокатит.
/// WE CAN'T change this elements
const btn = document.getElementById("btn_push");
let sendData = (timeFunc) => { console.log(`Function DONE! It took ${timeFunc} sec`)};
let randomInteger = (min, max) => {
let rand = min - 0.5 + Math.random() * (max - min + 1);
return Math.round(rand);
}
btn.addEventListener("click", function(){
const time = randomInteger(1000, 4000);
setTimeout(sendData(time), time);
});
/// OWN elements
let secondFunction = () => { console.log(`This function done after server get data`)};
sendData = new Proxy(sendData, {
apply: function(target, self, arg) {
target.apply(self, arg)
secondFunction()
}})
<button id='btn_push'>Тест</button>
Вот вариант с асинхронной функцией sendData...
/// WE CAN'T change this elements
const btn = document.getElementById("btn_push");
let sendData = (timeFunc) => new Promise(res => setTimeout(_ => {
console.log(`Function DONE! It took ${timeFunc} sec`)
res('какие-то данные')
}, timeFunc));
let randomInteger = (min, max) => {
let rand = min - 0.5 + Math.random() * (max - min + 1);
return Math.round(rand);
}
btn.addEventListener("click", function(){
const time = randomInteger(1000, 4000);
sendData(time)
.then(v => console.log('Обработка', v))
});
/// OWN elements
let secondFunction = () => { console.log(`This function done after server get data`)};
sendData = new Proxy(sendData, {
apply: async function(target, self, arg) {
const v = await target.apply(self, arg)
secondFunction()
return v
}})
<button id='btn_push'>Тест</button>