질문) 버튼 연타(?) 할 때 요청 중복되는 상황 다루기


(혜림) #1

날씨 데이터 가져오는 http request, 서버에 데이터 저장하는 http request가 버튼 누르는 대로 요청이 가더라고요.
화면에서 Refresh 버튼 누르면 geolocation 처리 중일 때 추가로 누른 횟수만큼 작업이 쌓이고,
서버 데이터는 Send 누르면 중복으로 입력한 내용이 저장이 되어서 이런 상황을 어떻게 다루면(?) 좋을지 궁금합니다.

서버에 중복된 내용 저장되는건 Send 누른 이후에는 input에 입력 된 값 초기화하고, 입력된 값 없으면 요청이 안 가게 UI에서 처리할 수 있을 것 같은데, geolocation이랑 weather api 호출 쌓이는건 다른 방법으로 처리해줘야 될 것 같아요.

그리고 이런 요청 완료되기 전에 취소 하려면… Promise 객체에서 처리해주면 될까요?


(코드종) #2

답변을 하기 전에… parse-server를 사용하고 계시군요. 반가워요. :blush:

lodash를 이용하고 있다면 _.debounce를 사용해보세요.
leading 옵션을 true로 사용하면 됩니다.

이런 중복적인 것을 다루는 것으로 _.throttle, _.once 등이 있는데 이런 경우에는 debouce가 적절합니다. :slight_smile:

간단히 이 들의 역할과 차이를 말하자면

  • debounce : 가장 최근 함수 실행한 시간 이후 특정시간내에 함수 실행이 있을 딱 한번만 실행되도록 한다. leading 옵션은 이렇게 특정 시간 이내에 반복된 함수 호출 중에 맨 처음 눌렸을 때 진짜로 실행할지 아니면 맨 마지막에 실행할지를 결정하는 옵션.
  • throttle : 특정시간내에 반복적인 실행을 무시한다. 단 특정시간 이후에는 실행됨, debouce는 꼬리에 꼬리를 무는 형태라면, throttle은 아무리 많이 눌러도 특정시간내에 한번만 실행되도록 하는 것
  • once : 그냥 무조건 한번만 실행되는 함수. 일반적으로 button에 사용하기에는 부적절.

요 내용으로 코드종 유튜브 영상 하나 나가야겠네요. 덕분에 소재 생겼네요.ㅎㅎ


(코드종) #3

(혜림) #4

오오 ㅎㅎㅎ 이렇게 간단하게 해결되는군요… 신기하고 좋네요 ㅋㅋㅋ

parse-server는 써보고 있는데 https 문제 해결을 못 했어요. heroku에 배포하고 도메인 있던거에 cloudflare 적용해봤는데 blocked:mixed-content 로 서버 접속이 안 되더라고요. 요청도 http, https 둘다 처리해줘야 될 것 같은데 (http를 https로 redirect(?) 시키는 것 같음) nginx를 쓰면 될까요? heroku nginx node example 참고해서 해봤는데 실패해서 재도전 해보려고 합니다 ㅋㅋ


(코드종) #5

개발할 때 localhost를 http로 쓸수 있어요.
그 외에 https이면 RN에 설정없이 그냥 사용이 가능합니다. (다만 https 인증서를 서버에 설정이 필요하긴 합니다.)
아마 node 서버를 https로 띄우지않고 http를 띄운 것 아닐까 생각이 드네요.

다음 예제를 이용하시나요? https로 띄울려면 다음 코드에서 http 대신에 httpsrequire하면 됩니다.

  • 방법 1: nginx없이 그냥 node만을 바로 사용하고 node에서 https로 서버를 시작해도 됩니다.
  • 방법 2 : node를 http로 띄우고 nginx를 앞에 둬서 nginx가 http를 받고 내부적으로 node와 http로 통신하도록 설정하면 됩니다.

제가 준비중인 fullstack 개발에 대한 강의에서 이 부분을 포함하고 있는데 그 강의를 언제 시작하게 될지는 미정입니다. ㅎㅎ

궁금증이 안 풀리시면 내일 강의 끝나기 전 QnA 시간에 알려주세요.


(정기욱) #6

debounce, throttle 뭔가 비슷하면서도 다른역할인데 실제 실무에서 쓸때도 햇갈리는경우가 많더라구요. :joy:


(혜림) #7

뭔가 설정 바꾼게 없는데 지금은 parse dashboard https로 접속이 되네요…? 허허ㅠㅠ 로그 보니까 서버 다운된 다음에 재실행 되었는데 그 이후로 되는 것 같긴 합니다. 말씀해주신 내용 참고해서 왜 돌아가는지 좀 더 찾아봐야겠어요. 아래는 서버 코드 기록용으로 같이 남겨요!

const express = require('express')
const http = require('http')
const https = require('https')
const fs = require('fs')
const dotenv = require('dotenv')

if (process.env.NODE_ENV === 'dev'){
  const envConfig = dotenv.parse(fs.readFileSync('.env'))
  for (let i in envConfig) {
    process.env[i] = envConfig[i]
  }
}

const ParseServer = require('parse-server').ParseServer
const ParseDashboard = require('parse-dashboard')

require('dotenv').config()

const app = express()
const port = process.env.PORT

// const verification = {
//   key: fs.readFileSync('./ssl/key.pem'),
//   cert: fs.readFileSync('./ssl/cert.pem')
// }

const api = new ParseServer({
  databaseURI: process.env.MONGODB_URI,
  appId: process.env.APP_ID,
  masterKey: process.env.MASTER_KEY, 
  serverURL: process.env.SERVER_URL, 
})

const options = { allowInsecureHTTP: true }

const dashboard = new ParseDashboard({
	"apps": [{
	  "serverURL": process.env.SERVER_URL,
	  "appId": process.env.APP_ID,
	  "masterKey": process.env.MASTER_KEY,
	  "appName": process.env.APP_ID
  }],
  "users": [
    {
      "user": process.env.USER_ID,
      "pass": process.env.PASS
    }
  ]
}, options)

app.use(express.urlencoded())
app.use('/parse', api)
app.use('/dashboard', dashboard)

app.get('/', (req, res) => {
  res.redirect('/dashboard')
})

// Run separate https server if on localhost
// if (process.env.NODE_ENV !== 'production'){
//   https.createServer(verification, app).listen(process.env.PORT, () => {
//     console.log(`Dev Https Server listening on port ${port}`)
//   })
// }

// if (process.env.NODE_ENV === 'production'){
//   app.use((req, res, next) => {
//     res.setHeader('Strict-Transport-Security', 'max-age=8640000; includeSubDomains')
//     if (req.headers['x-forwarded-proto'] && req.headers['x-forwarded-proto'] === "http") {
//       return res.redirect(301, 'https://' + req.host + req.url)
//     } else {
//       return next()
//     }
//   })
// } else {
//   app.use((req, res, next) => {
//     res.setHeader('Strict-Transport-Security', 'max-age=8640000; includeSubDomains')
//     if ( !req.secure ) {
//       return res.redirect(301, 'https://' + req.host + ":" + process.env.PORT + req.url)
//     } else {
//       return next()
//     }
//   })
// }
http.createServer(app).listen(port, () => {
  console.log(`Http Server listening on port ${port}`)
})

// https.createServer(verification, app).listen(port, () => {
//   console.log(`Https Server listening on port ${port}`)
// })

그리고 실례 안 된다면 개발 서버/프로덕션 서버 분리(?) 하는 법, 도커로 개발하는 내용도 강의로 다루시는지 여쭤봐도 될까요? 필요한데 여기저기 흩어진 내용 본 걸로는 구조 잡기가 쉽지 않더라구요 :pensive:


(코드종) #8

heroku에 올린 거에 접속 가능하다는 건가요? 그럼 heroku에서 앞단에 https를 해주는 서비스가 있나보군요. :slight_smile:

풀스텍 강의에서 docker는 따로 계획에 없고 aws elastic beanstalk로 production/develop 등 서버 환경 설정을 다루는 내용은 포함할 예정이에요. 아직 강의 기획 단계이다보니 언제든지 변경 될 수 있어요. ㅎㅎ


(코드종) #9

이미 보셨을지 모르지만 기록차원에서 여기에도 throttle과 debounce 관련 코드종 영상 남겨 놓습니다. :slight_smile: