【问题标题】:JSHint, For Loops, Promises and one pesky lint errorJSHint、For 循环、Promises 和一个讨厌的 lint 错误
【发布时间】:2017-06-29 23:15:09
【问题描述】:

我的 JavaScript 中有一种情况,我正在生成许多承诺,我想在每个承诺上附加 then/catch 条件以处理个别问题。

我正在使用 RSVP Promise 库,它允许我使用 allSettled 来确定所有承诺何时都已解决。 RSVP 的allSettled 确实让我评估了在所有已解决的承诺结束时成功和失败的输出,但是通过将then/catch 添加到每个承诺中,我可以更好地控制如果某个特定的承诺该怎么做未履行承诺(例如,提示用户仅使用失败的那些重试等)。

使用我可信赖的 linter (JSHint),我不断收到“Don't make functions within a loop.”对我大喊大叫,我真的希望能够在没有这种 lint 的情况下将 then/catch 条件附加到每个 Promise出现错误。

我很好奇其他人如何绕过 JSHint 错误(除了更改 JSHint 规则。我认为这是一个很好的规则!)或者如果有人对如何处理我生成的 Promise 有更好的想法'@ 987654331@/catch 用例。

这是一个例子:

let Promise = RSVP.Promise
let people = ['Marty McFly', 'Doc', 'Robocop', 'Terminator', 'Bozo']
let sendMessagesToPeople = []
let thoseSucceeded = []
let thoseFailed = []

// Dummy Promise method to send a message to a person
function sendMessageToPerson (person, msg) {
  console.log(`Sending message to ${person}...`)
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if (Math.random() > 0.5) {
        console.log(`✔︎ Sent "${msg}" to ${person}`)
        resolve(person, msg)
        return
      }
      console.log(`✘ Failed sending "${msg}" to ${person}`)
      reject(person, msg)
    }, 1000 + (Math.random() * 2000))
  })
}

// Generate the array of Promises for allSettled to process
for (let i = 0; i < people.length; i++) {
  let trySendMessageToPerson = sendMessageToPerson(people[i], "Hi there!")
    /* Illegal, according to JSHint */
    .then(() => {
      thoseSucceeded.push(people[i])
    })
    .catch(() => {
      thoseFailed.push(people[i])
    })

  sendMessagesToPeople.push(trySendMessageToPerson)
}

RSVP.allSettled(sendMessagesToPeople).then(() => {
  console.log(`Succeeded: ${thoseSucceeded.length}, Failed: ${thoseFailed.length}`)
})
&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/rsvp/3.3.3/rsvp.min.js"&gt;&lt;/script&gt;

编辑:

我真的很好奇 forforEachmap 的性能差异,所以使用 @rasmeister 和 @hackerrdave 给出的答案,我设计了一个 JSPerf 测试来尝试查看哪些循环更多高性能(为了好玩,我还进行了while 测试): https://jsperf.com/for-foreach-map-while-loop-performance-testing

在我的测试中,结果差异很大并且非常不确定,所以我不知道哪个循环实现在性能方面更好,但就可读性而言,我认为我必须选择map 选项。

【问题讨论】:

    标签: javascript promise jshint lint rsvp.js


    【解决方案1】:

    let Promise = RSVP.Promise
    let people = ['Marty McFly', 'Doc', 'Robocop', 'Terminator', 'Bozo']
    let thoseSucceeded = []
    let thoseFailed = []
    
    // Dummy Promise method to send a message to a person
    function sendMessageToPerson (person, msg) {
      console.log(`Sending message to ${person}...`)
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          if (Math.random() > 0.5) {
            console.log(`✔︎ Sent "${msg}" to ${person}`)
            resolve(person, msg)
            return
          }
          console.log(`✘ Failed sending "${msg}" to ${person}`)
          reject(person, msg)
        }, 1000 + (Math.random() * 2000))
      })
    }
    
    let sendMessagesToPeople = people.map((person) => {
      return sendMessageToPerson(person, "Hi there!")
      .then(() => {
          thoseSucceeded.push(person)
        })
        .catch(() => {
          thoseFailed.push(person)
        })
    })
    
    RSVP.allSettled(sendMessagesToPeople).then(() => {
      console.log(`Succeeded: ${thoseSucceeded.length}, Failed: ${thoseFailed.length}`)
    })
    &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/rsvp/3.3.3/rsvp.min.js"&gt;&lt;/script&gt;

    这会将 Promise 收集到一个数组中,然后您可以在其中对所有的 m 做出响应。

    【讨论】:

      【解决方案2】:

      您只需从循环中删除函数定义 - 您可以将循环中的所有逻辑提取到一个函数中,然后在 forEach 中使用它:

      people.forEach(sendMessage);
      
      function sendMessage(person) {
        let trySendMessageToPerson = sendMessageToPerson(person, "Hi there!")
          .then(thoseSucceded.push)
          .catch(thoseFailed.push);
      
        sendMessagesToPeople.push(trySendMessageToPerson);
      }
      

      【讨论】:

        【解决方案3】:

        您可以定义传递给thencatch 的这两个函数——现在在每次迭代中定义——只定义一次:

        let addSuccess = person => thoseSucceeded.push(person);
        let addFailure = person => thoseFailed.push(person);
        

        ...然后:

        let trySendMessageToPerson = sendMessageToPerson(people[i], "Hi there!")
            .then(addSuccess)
            .catch(addFailure)
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-10-04
          • 2010-11-19
          • 2021-05-10
          • 1970-01-01
          相关资源
          最近更新 更多