如何在不重复代码的情况下编写此函数,遵循 DRY 原则

How do I write this function without duplicating code, following the DRY principle

我想开始改进我的代码编写方式而不复制它,著名的干净代码,我想开始将它应用于已经使用的小函数。 我如何在不复制 开关条件 甚至 创建 class 并使用 多态性 因为功能超级相似

/**
 * Wait for an element and type on it
 * @param {puppeteer.Page} page - Context page
 * @param {string} selector - Element selector (CSS, xpath)
 * @param {string} text - Text to be typed in the element
 * @param {string} waitType - Element type (CSS, xpath)
 */
const waitAndType = async (page, selector, text, waitType = 'selector') => {
  switch (waitType) {
    case 'selector':
      await page.waitForSelector(selector)
      break
  }
  await page.type(selector, text)
}
// ===========================================

/**
 * Wait for an element and click on it
 * @param {puppeteer.Page} page - Context page
 * @param {string} selector - Element selector (CSS, xpath)
 * @param {string} waitType - Element type (CSS, xpath)
 */
const waitAndClick = async (page, selector, waitType = 'selector') => {
  switch (waitType) {
    case 'selector':
      await page.waitForSelector(selector)
      break
    case 'xpath':
      await page.waitForXPath(selector)
      break
  }
  await page.click(selector)
}
// ===========================================

// ===========================================
module.exports = {
  waitAndType,
  waitAndClick,
}
// ===========================================

您可以向您的函数传递一个额外的参数,例如 actionType。根据您的需要(键入并单击),它可以有两个或多个可能的值。

您可以按如下方式重写您的函数:

const waitAndPerformAction = async (page, selector, waitType = 'selector', actionType) => {
  switch (waitType) {
    case 'selector':
      await page.waitForSelector(selector)
      break
    case 'xpath':
      await page.waitForXPath(selector)
      break
  }
  if(actionType === 'type') {
    await page.type(selector)
  } else if(actionType === 'click`) {
     await page.click(selector)
  }
}

您可以更进一步,在单独的文件(可能是常量文件)中定义您的 action,您可以在其中定义所有操作类型,以避免在整个代码库中出现任何拼写错误。

类似于:

const ACTION_TYPES = {
  CLICK: 'click',
  TYPE: 'type',
 ....
}

然后将 ACTION_TYPES.CLICKACTION_TYPES.TYPE 作为 argument 传递给您的函数并修改您的 waitAndPerformAction 函数。

const waitAndPerformAction = async (page, selector, waitType = 'selector', actionType) => {
  switch (waitType) {
    case 'selector':
      await page.waitForSelector(selector)
      break
    case 'xpath':
      await page.waitForXPath(selector)
      break
  }
 await page[ACTION_TYPES[actionType]]();
}

并且,最后将您的函数调用为:

waitAndPerformAction(..other arguments, ACTION_TYPES.CLICK)