【问题标题】:Alternative to global variable when using clearTimeout & setTimeout使用 clearTimeout 和 setTimeout 时替代全局变量
【发布时间】:2022-01-25 14:16:10
【问题描述】:

编辑 我在标题和问题中使用了错误的术语。我的意思不是全局变量,而是在 showNotification 函数中声明timeoutID

我正在测试 Redux 的第一周。我想知道是否有更优雅/更少hacky的解决方案来为 timeoutID 使用 glodal 变量? clearTimeout 用于保证最后添加的通知始终显示完整的所需时间,即使它会在上一个通知设置为“空”之前添加。

actionCreator.js

import { addQuote } from "./addQuote"
import { showNotification } from "./showNotification"

export const actionCreator = (quote, time) => {
  return dispatch => {
    dispatch(addQuote(quote))
    dispatch(showNotification(quote, time))
  }
}

showNotification.js

let timeoutID = null

export const showNotification = (newQuote, time) => {

  const message = `A new quote by ${newQuote.author} was added.`
  return dispatch => {
    dispatch({ type: 'SHOW_NOTIFICATION', data: message })

    clearTimeout(timeoutID)
    
    timeoutID = setTimeout(() => {
      dispatch({ type: 'SHOW_NOTIFICATION', data: '' })
    }, time * 1000)
    
  }
}

notificationReducer.js

const initState = {
  notification: ''
}

const notificationReducer = (state=initState, action) => {
  switch (action.type) {
    case 'SHOW_NOTIFICATION':

    const message = action.data
      return {
        ...state,
        notification: message
      }

    default:
      return {
        ...state
      }
  }
}

export default notificationReducer

【问题讨论】:

  • 它不是全局的,它是一个闭包,这是使模块世界工作的核心原则之一。如果它是全局变量,您可以在任何其他 JS 文件中使用该变量,而无需显式导入它。在actionCreator.jsimport { showNotification } from "./showNotification" 尝试console.log(timeoutID),你会得到undefined。以这种方式编程不仅没有错。它是最先进的,与传递参数相比,它是解决问题的一种非常优雅的方式。
  • 我明白了,我用错了术语。我的意思是,是否可以在 showNotification 函数中声明 timeoutID。
  • 是的,就像使用 message 一样。与任何闭包一样,您只需要确保变量在函数的范围内在声明函数时
  • 如果我在 message 之类的函数中声明 timeoutID 并且我想显示通知,例如5 秒并在第一个通知清除之前添加新报价,第二个通知仅在“原始”5 秒的剩余时间内显示。当 timeoutID 在最后添加的引号之外声明时,始终显示完整的所需时间。
  • 啊,你是对的,原因是每次你调用showNotifcations,如果你在里面声明timeoutId,你就会创建一个新的局部变量。所以在这种情况下,如果你只想存在一个变量timeoutId,你需要在外面声明它,所以它只会在导入文件时创建。

标签: javascript redux


【解决方案1】:

不是全局的,它是一个闭包,这是模块世界的核心原则之一(发明它是为了规避使用全局命名空间!)。

如果它全局变量,您可以在任何其他 JS 文件中使用该变量,而无需显式导入它。

actionCreator.js 中,在import { showNotification } from "./showNotification" 中,尝试console.log(timeoutID),你会得到undefined

闭包其实并不复杂;它只是意味着任何函数在声明时都会“记住”在函数声明时已知的任何局部变量(“在范围内”是“已知”在技术上更正确的术语),无论函数何时被叫,或谁叫它。通过这种机制为函数所知的那些变量称为闭包

以这种方式编程不仅没有错;它也是最先进的,与其他更冗长和冗长的解决方案(如传递参数)相比,这是解决问题的最优雅的方式。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-10-06
    • 1970-01-01
    • 2021-07-18
    • 1970-01-01
    • 2012-07-01
    • 1970-01-01
    • 2022-10-14
    相关资源
    最近更新 更多