JSHint,For Loops,Promises和一个讨厌的lint错误

时间:2017-02-11 17:49:25

标签: javascript promise jshint lint rsvp.js

我的JavaScript中存在一些情况,我正在生成一些承诺,我希望将then / catch条件附加到每个承诺上以处理各个问题。

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

使用我可信赖的linter(JSHint),我不停地“Don't make functions within a loop.”向我大喊,我真的希望能够将then / catch条件附加到每个没有出现这种皮棉错误的承诺。

我很好奇其他人是如何解决这个问题的JSHint错误(除了改变JSHint规则。我认为这是一个很好的规则!)或者如果有人更好地了解如何处理我生成的Promises'{ {1}} / then用例。

以下是一个例子:

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}`)
})

编辑:

我对<script src="https://cdnjs.cloudflare.com/ajax/libs/rsvp/3.3.3/rsvp.min.js"></script>forforEach的性能差异感到很好奇,所以使用@rasmeister和@hackerrdave给出的答案我设计了一个JSPerf测试试图看到哪个循环的性能更高(我还参加了map测试以获得乐趣): https://jsperf.com/for-foreach-map-while-loop-performance-testing

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

3 个答案:

答案 0 :(得分:0)

&#13;
&#13;
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}`)
})
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/rsvp/3.3.3/rsvp.min.js"></script>
&#13;
&#13;
&#13;

这会将promises收集到一个数组中,然后你可以响应m all。

答案 1 :(得分:0)

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

people.forEach(sendMessage);

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

  sendMessagesToPeople.push(trySendMessageToPerson);
}

答案 2 :(得分:0)

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

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

......然后:

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