防止提交按钮触发多个获取请求
Prevent submit button from firing multiple fetch requests
我在网页上有一个部分用于任务:
在表单中我写了一封电子邮件 'validated' 后来 function.First 当我提交一封通过验证的电子邮件时它会向服务器发送一个 sendSubscribe 函数,之后我点击取消订阅按钮,它发送一个取消订阅用户 function.But,之后,当我点击电子邮件输入时,它开始发送取消订阅提取请求,当我点击订阅按钮时,它也做同样的事情。
网络选项卡如下所示:
我想我知道问题出在哪里,但我不知道如何解决 it.My 我的想法是,每次我单击订阅按钮时,它都会从函数中附加一个事件侦听器,这就是它触发多个事件的原因取消订阅请求。
订阅功能:订阅邮箱最重要
import { validateEmail } from './email-validator.js'
import { unsubscribeUser } from './unsubscribeFetch.js'
export const subscribe = () => {
const subscribeBtn = document.getElementById('subscribeButton')
subscribeBtn.setAttribute('value', 'Unsubscribe')
document.getElementById('emailForm').style.display = 'none'
localStorage.setItem('isSubscribed', 'true')
document.getElementById('submit-info').value = ''
}
export const unsubscribe = () => {
const subscribeBtn = document.getElementById('subscribeButton')
subscribeBtn.setAttribute('value', 'Subscribe')
document.getElementById('emailForm').style.display = 'block'
localStorage.setItem('isSubscribed', 'false')
}
export const subscribeEmail = (email) => {
const isValidEmail = validateEmail(email)
if (isValidEmail === true) {
subscribe()
document.querySelector('form').addEventListener('click', function (e) {
unsubscribe()
unsubscribeUser()
localStorage.removeItem('Email')
e.stopPropagation()
})
} else if (isValidEmail === false) {
unsubscribe()
}
}
订阅获取函数:
import { validateEmail } from './email-validator.js'
export const sendSubscribe = (emailInput) => {
const isValidEmail = validateEmail(emailInput)
if (isValidEmail === true) {
sendData(emailInput)
}
}
export const sendHttpRequest = (method, url, data) => {
return fetch(url, {
method: method,
body: JSON.stringify(data),
headers: data
? {
'Content-Type': 'application/json'
}
: {}
}).then(response => {
if (response.status >= 400) {
return response.json().then(errResData => {
const error = new Error('Something went wrong!')
error.data = errResData
throw error
})
}
return response.json()
})
}
const sendData = (emailInput) => {
sendHttpRequest('POST', 'http://localhost:8080/subscribe', {
email: emailInput
}).then(responseData => {
return responseData
}).catch(err => {
console.log(err, err.data)
window.alert(err.data.error)
})
}
退订获取功能:
export const unsubscribeUser = () => {
fetch('http://localhost:8080/unsubscribe', { method: 'POST' }).then(response => { console.log(response.status) })
}
订阅按钮事件监听器:
document.querySelector('form').addEventListener('submit', async function (e) {
// create a variable to store localStorage email value
const introducedEmail = inputForm.value
e.preventDefault()
console.log(introducedEmail)
localStorage.setItem('Email', introducedEmail)
subscribeEmail(introducedEmail) //change the button style and set in local storage isSubscribed to true
sendSubscribe(introducedEmail) //send subscribe fetch to the server
// prevent additional requests upon clicking on "Subscribe" and "Unsubscribe".
if (isFetching) return // do nothing if request already made
isFetching = true
disableBtn()
const response = await fetchMock() //eslint-disable-line
isFetching = false
enableBtn()
})
// 用于在获取请求正在进行时禁用提交按钮的函数
const fetchMock = () => {
return new Promise(resolve => setTimeout(() => resolve('hello'), 2000))
}
const disableBtn = () => {
submitForm.setAttribute('disabled', 'disabled')
submitForm.style.opacity = '0.5'
}
const enableBtn = () => {
submitForm.removeAttribute('disabled')
submitForm.style.opacity = '1'
}
}
你们能帮帮我吗?我不知道如何提前修复this.Thanks!
我修改了你所有的功能并解决了你的问题,实现了async和await。
https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Asynchronous/Async_await
订阅获取函数
import { validateEmail } from './email-validator.js'
export const sendSubscribe = async (emailInput) => {
const isValidEmail = validateEmail(emailInput) // idk if this is async func
if (isValidEmail === true) {
await sendData(emailInput);
}
}
export const sendHttpRequest = async (method, url, data) => {
return await fetch(url, {
method: method,
body: JSON.stringify(data),
headers: data
? {
'Content-Type': 'application/json'
}
: {}
}).then(response => {
if (response.status >= 400) {
return response.json().then(errResData => {
const error = new Error('Something went wrong!')
error.data = errResData
throw error
})
}
return response.json()
})
}
const sendData = async (emailInput) => {
await sendHttpRequest('POST', 'http://localhost:8080/subscribe', {
email: emailInput
}).then(responseData => {
return responseData
}).catch(err => {
console.log(err, err.data)
window.alert(err.data.error)
})
}
退订获取功能
export const unsubscribeUser = async () => {
await fetch('http://localhost:8080/unsubscribe', { method: 'POST' }).then(response => { console.log(response.status) })
}
订阅按钮事件监听器
let isFetching = false;
document.querySelector('form').addEventListener('submit', async function (e) {
e.preventDefault();
if (isFetching) return // do nothing if request already made
// create a variable to store localStorage email value
const introducedEmail = inputForm.value;
console.log(introducedEmail);
localStorage.setItem('Email', introducedEmail);
// prevent additional requests upon clicking on "Subscribe" and "Unsubscribe".
disableBtn();
await fetchMock();
isFetching = true;
await subscribeEmail(introducedEmail); //change the button style and set in local storage isSubscribed to true
await sendSubscribe(introducedEmail); //send subscribe fetch to the server
// data sent, reenabling button
isFetching = true
enableBtn();
});
// 用于在获取请求正在进行时禁用提交按钮的函数
...
const fetchMock = () => {
return new Promise(resolve => setTimeout(() => resolve('hello'), 2000))
}
const disableBtn = () => {
submitForm.setAttribute('disabled', 'disabled')
submitForm.style.opacity = '0.5'
}
const enableBtn = () => {
submitForm.removeAttribute('disabled')
submitForm.style.opacity = '1'
}
}
所以,就像我说的,问题出在将新事件侦听器附加到按钮的函数中,这就是为什么每次发送取消订阅请求时都会再发送 +1 个请求。所以,我这样做了:
提交按钮的功能:
let isUsed = false
const submitClickButton = async () => {
// create a variable to store localStorage email value
const introducedEmail = inputForm.value
//e.preventDefault()
console.log(introducedEmail)
localStorage.setItem('Email', introducedEmail)
subscribeEmail(introducedEmail) //change the button style and set in local storage isSubscribed to true
sendSubscribe(introducedEmail) //send subscribe fetch to the server
// prevent additional requests upon clicking on "Subscribe" and "Unsubscribe".
if (isFetching) return // do nothing if request already made
isFetching = true
disableBtn()
const response = await fetchMock() //eslint-disable-line
isFetching = false
enableBtn()
isUsed = true
}
const undoClickButton = () => {
//e.preventDefault()
//unsubscribeEmail()
unsubscribeEmail()
isUsed = false
}
const toggleButton = () => {
isUsed ? undoClickButton() : submitClickButton()
}
submitForm.addEventListener('click', toggleButton, false)
和订阅电子邮件功能:
export const subscribeEmail = (email) => {
const isValidEmail = validateEmail(email)
if (isValidEmail === true) {
subscribe()
// document.querySelector('form').addEventListener('click', function (e) {
// unsubscribe()
// unsubscribeUser()
// localStorage.removeItem('Email')
// e.stopPropagation()
// })
} else if (isValidEmail === false) {
unsubscribe()
}
}
export const unsubscribeEmail = () => {
// const isValidEmail = validateEmail(email)
// if (isValidEmail===true){
unsubscribe()
unsubscribeUser()
localStorage.removeItem('Email')
//}
}
我在网页上有一个部分用于任务:
在表单中我写了一封电子邮件 'validated' 后来 function.First 当我提交一封通过验证的电子邮件时它会向服务器发送一个 sendSubscribe 函数,之后我点击取消订阅按钮,它发送一个取消订阅用户 function.But,之后,当我点击电子邮件输入时,它开始发送取消订阅提取请求,当我点击订阅按钮时,它也做同样的事情。
网络选项卡如下所示:
我想我知道问题出在哪里,但我不知道如何解决 it.My 我的想法是,每次我单击订阅按钮时,它都会从函数中附加一个事件侦听器,这就是它触发多个事件的原因取消订阅请求。
订阅功能:订阅邮箱最重要
import { validateEmail } from './email-validator.js'
import { unsubscribeUser } from './unsubscribeFetch.js'
export const subscribe = () => {
const subscribeBtn = document.getElementById('subscribeButton')
subscribeBtn.setAttribute('value', 'Unsubscribe')
document.getElementById('emailForm').style.display = 'none'
localStorage.setItem('isSubscribed', 'true')
document.getElementById('submit-info').value = ''
}
export const unsubscribe = () => {
const subscribeBtn = document.getElementById('subscribeButton')
subscribeBtn.setAttribute('value', 'Subscribe')
document.getElementById('emailForm').style.display = 'block'
localStorage.setItem('isSubscribed', 'false')
}
export const subscribeEmail = (email) => {
const isValidEmail = validateEmail(email)
if (isValidEmail === true) {
subscribe()
document.querySelector('form').addEventListener('click', function (e) {
unsubscribe()
unsubscribeUser()
localStorage.removeItem('Email')
e.stopPropagation()
})
} else if (isValidEmail === false) {
unsubscribe()
}
}
订阅获取函数:
import { validateEmail } from './email-validator.js'
export const sendSubscribe = (emailInput) => {
const isValidEmail = validateEmail(emailInput)
if (isValidEmail === true) {
sendData(emailInput)
}
}
export const sendHttpRequest = (method, url, data) => {
return fetch(url, {
method: method,
body: JSON.stringify(data),
headers: data
? {
'Content-Type': 'application/json'
}
: {}
}).then(response => {
if (response.status >= 400) {
return response.json().then(errResData => {
const error = new Error('Something went wrong!')
error.data = errResData
throw error
})
}
return response.json()
})
}
const sendData = (emailInput) => {
sendHttpRequest('POST', 'http://localhost:8080/subscribe', {
email: emailInput
}).then(responseData => {
return responseData
}).catch(err => {
console.log(err, err.data)
window.alert(err.data.error)
})
}
退订获取功能:
export const unsubscribeUser = () => {
fetch('http://localhost:8080/unsubscribe', { method: 'POST' }).then(response => { console.log(response.status) })
}
订阅按钮事件监听器:
document.querySelector('form').addEventListener('submit', async function (e) {
// create a variable to store localStorage email value
const introducedEmail = inputForm.value
e.preventDefault()
console.log(introducedEmail)
localStorage.setItem('Email', introducedEmail)
subscribeEmail(introducedEmail) //change the button style and set in local storage isSubscribed to true
sendSubscribe(introducedEmail) //send subscribe fetch to the server
// prevent additional requests upon clicking on "Subscribe" and "Unsubscribe".
if (isFetching) return // do nothing if request already made
isFetching = true
disableBtn()
const response = await fetchMock() //eslint-disable-line
isFetching = false
enableBtn()
})
// 用于在获取请求正在进行时禁用提交按钮的函数
const fetchMock = () => {
return new Promise(resolve => setTimeout(() => resolve('hello'), 2000))
}
const disableBtn = () => {
submitForm.setAttribute('disabled', 'disabled')
submitForm.style.opacity = '0.5'
}
const enableBtn = () => {
submitForm.removeAttribute('disabled')
submitForm.style.opacity = '1'
}
}
你们能帮帮我吗?我不知道如何提前修复this.Thanks!
我修改了你所有的功能并解决了你的问题,实现了async和await。
https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Asynchronous/Async_await
订阅获取函数
import { validateEmail } from './email-validator.js'
export const sendSubscribe = async (emailInput) => {
const isValidEmail = validateEmail(emailInput) // idk if this is async func
if (isValidEmail === true) {
await sendData(emailInput);
}
}
export const sendHttpRequest = async (method, url, data) => {
return await fetch(url, {
method: method,
body: JSON.stringify(data),
headers: data
? {
'Content-Type': 'application/json'
}
: {}
}).then(response => {
if (response.status >= 400) {
return response.json().then(errResData => {
const error = new Error('Something went wrong!')
error.data = errResData
throw error
})
}
return response.json()
})
}
const sendData = async (emailInput) => {
await sendHttpRequest('POST', 'http://localhost:8080/subscribe', {
email: emailInput
}).then(responseData => {
return responseData
}).catch(err => {
console.log(err, err.data)
window.alert(err.data.error)
})
}
退订获取功能
export const unsubscribeUser = async () => {
await fetch('http://localhost:8080/unsubscribe', { method: 'POST' }).then(response => { console.log(response.status) })
}
订阅按钮事件监听器
let isFetching = false;
document.querySelector('form').addEventListener('submit', async function (e) {
e.preventDefault();
if (isFetching) return // do nothing if request already made
// create a variable to store localStorage email value
const introducedEmail = inputForm.value;
console.log(introducedEmail);
localStorage.setItem('Email', introducedEmail);
// prevent additional requests upon clicking on "Subscribe" and "Unsubscribe".
disableBtn();
await fetchMock();
isFetching = true;
await subscribeEmail(introducedEmail); //change the button style and set in local storage isSubscribed to true
await sendSubscribe(introducedEmail); //send subscribe fetch to the server
// data sent, reenabling button
isFetching = true
enableBtn();
});
// 用于在获取请求正在进行时禁用提交按钮的函数
...
const fetchMock = () => {
return new Promise(resolve => setTimeout(() => resolve('hello'), 2000))
}
const disableBtn = () => {
submitForm.setAttribute('disabled', 'disabled')
submitForm.style.opacity = '0.5'
}
const enableBtn = () => {
submitForm.removeAttribute('disabled')
submitForm.style.opacity = '1'
}
}
所以,就像我说的,问题出在将新事件侦听器附加到按钮的函数中,这就是为什么每次发送取消订阅请求时都会再发送 +1 个请求。所以,我这样做了:
提交按钮的功能:
let isUsed = false
const submitClickButton = async () => {
// create a variable to store localStorage email value
const introducedEmail = inputForm.value
//e.preventDefault()
console.log(introducedEmail)
localStorage.setItem('Email', introducedEmail)
subscribeEmail(introducedEmail) //change the button style and set in local storage isSubscribed to true
sendSubscribe(introducedEmail) //send subscribe fetch to the server
// prevent additional requests upon clicking on "Subscribe" and "Unsubscribe".
if (isFetching) return // do nothing if request already made
isFetching = true
disableBtn()
const response = await fetchMock() //eslint-disable-line
isFetching = false
enableBtn()
isUsed = true
}
const undoClickButton = () => {
//e.preventDefault()
//unsubscribeEmail()
unsubscribeEmail()
isUsed = false
}
const toggleButton = () => {
isUsed ? undoClickButton() : submitClickButton()
}
submitForm.addEventListener('click', toggleButton, false)
和订阅电子邮件功能:
export const subscribeEmail = (email) => {
const isValidEmail = validateEmail(email)
if (isValidEmail === true) {
subscribe()
// document.querySelector('form').addEventListener('click', function (e) {
// unsubscribe()
// unsubscribeUser()
// localStorage.removeItem('Email')
// e.stopPropagation()
// })
} else if (isValidEmail === false) {
unsubscribe()
}
}
export const unsubscribeEmail = () => {
// const isValidEmail = validateEmail(email)
// if (isValidEmail===true){
unsubscribe()
unsubscribeUser()
localStorage.removeItem('Email')
//}
}