没有异步代码的JavaScript竞争条件?

时间:2018-03-12 12:50:15

标签: javascript

即使我没有在其中使用异步函数,我似乎遇到了具有我的函数的竞争条件

window.focusElem = (elem, overrideGroupNextFocus) => {
  if (!elem) return
  console.log(`FOCUS: ${elem.id}`)

  if (store.getState().app.isExitVisible &&
    elem.id !== 'exitExitButton' &&
    elem.id !== 'exitBackButton'
  ) {
    return
  }

  // Remove focus class from existing focused elements
  Array.from(document.querySelectorAll('.focus')).forEach(e => {
    console.log(`FOCUS: ${elem.id} removing focus from ${e.id}`)
    e.classList.remove('focus')
  })

  const parentFocusGroup = findParentFocusGroup(elem)
  let elemToFocus = elem
  const focusGroupNextFocusId = parentFocusGroup ? parentFocusGroup.getAttribute('data-focusgroup-next-focus') : ''
  if (!overrideGroupNextFocus &&
    focusGroupNextFocusId &&
    document.activeElement.id !== focusGroupNextFocusId) {
    elemToFocus = parentFocusGroup.querySelector(`#${focusGroupNextFocusId}`) || elem
  }

  store.dispatch(setFocusElem(elemToFocus.id))
  if (elemToFocus.id.startsWith('appNav')) {
    Array.from(document.querySelectorAll('.active')).forEach(e => e.classList.remove('active'))
    elemToFocus.classList.add('active')
    document.querySelector('.app-wrapper').setAttribute('data-sidebar', 'open')
  } else if (!elemToFocus.hasAttribute('data-focus-inmodal')) {
    document.querySelector('.app-wrapper').setAttribute('data-sidebar', 'closed')
  }
  lastFocused = elemToFocus
  console.log(`FOCUS: ${elem.id} add focus to ${elemToFocus.id}`)
  elemToFocus.classList.add('focus')
  document.dispatchEvent(new CustomEvent('app:focusChanged', { detail: elemToFocus }))
}

function findParentFocusGroup(elem) {
  if (elem.hasAttribute('data-focusgroup')) {
    return elem
  }

  const parent = elem.parentNode
  if (parent && parent.nodeType !== 9) return findParentFocusGroup(parent)
}

我注意到如果快速连续调用此函数,我可以在控制台中获得以下输出:

FOCUS: history0
FOCUS: history0 removing focus from vodBannerProgram
FOCUS: vodBannerProgram
FOCUS: vodBannerProgram add focus to vodBannerProgram
FOCUS: history0 add focus to history0

注意,似乎首先为history0 vodBannerProgram调用此函数。但似乎它在history0中途执行,然后再次前进到vodBannerProgramforEach同步正确吗?

1 个答案:

答案 0 :(得分:0)

没有异步就没有竞争条件。您没有显示足够的代码来查找它(如果是这种情况)。请检查以下代码:

  1. setFocusElem
  2. store.dispatch