I met these two function programming questions in the interview yesterday, but damn it, I had no idea at all (sad)

  1. Use Promise to complete a queue. If the number of tasks in the queue is full, the subsequent tasks will not be executed. When the tasks in the queue are in the completed state, new tasks will be added to the queue

  2. Complete a retry function, pass in an execution function and a counter, and retry the function until it succeeds if it fails a certain number of times

After the interview, I searched the Internet for similar questions. Here are my ideas after the summary and the successful code

Promise the queue

There are several key points to this question

  • Queue: Stores the queue of unexecuted tasks
  • Counter: Stores the number of tasks currently being executed
  • Maximum number of tasks to be executed
  • Add task function
  • Execute task function

Next, create a task queue execution class based on the focus we described above

  class Scheduler {
    // Initializes the task queue and limits the maximum number of executions based on incoming numbers
    constructor(maxCount) {
      this.maxCount = count
      this.list = []
      this.count = 0
    }
    add(){}start(){}}Copy the code

Now we’re going to write the add function, and before we write the add function, let’s first think about what we should pay attention to inside the add function

First, the add function must return a promise function if we want to perform an operation on the result after the task completes

  add(task) {
    return new Promise(resolve= > {
      resolve()
    })
  }
Copy the code

When adding a task, we need to add the task to the store of the unexecuted task queue

  add(task) {
    return new Promise(resolve= > {
      resolve(() = > {
        this.list.push(task())
      })
    })
  }
Copy the code

That’s where the question comes in, how do we monitor whether the task has been completed, and that’s where the promise comes in, so we can tell in then whether the function has been successfully executed

  add(task) {
    return new Promise(resolve= > {
      resolve(() = > {
        this.list.push(Promise.resolve(task()).then())
        // If the return value after task execution is a Promise object, it can be modified to the following form
        // this.list.push(task().then())})})}Copy the code

The add function starts here, and then we write the execute function, and in the start function all we need to do is check if the number of tasks in progress is less than the maximum number of tasks, and then pull a task from the queue and execute it, and then add one to the number of tasks in progress

  start() {
    if(this.count < this.maxCount) {
      this.count++
      this.list[0] && this.list.shift()()
    }
  }
Copy the code

Next, modify the add function so that when we add a task, we execute the execution function at the end, reduce the number of execution queues and trigger the execution function when the execution task is complete, and finally return the value of the task

  add(task) {
    return new Promise(resolve= > {
      this.list.push(() = > {
        resolve(Promise.resolve(task()).then(s= > {
          this.count--
          this.start()
          return s
        }))
      })
      this.start()
    })
  }
Copy the code

Next, instantiate the task queue and create an asynchronous execution method and an add task function

  let scheduler = new Scheduler(5)
  let timeout = (time) = > {
    return new Promise(resolve= > {
      setTimeout(resolve, time)
    })
  }

  let addTask = function addTask(time, order) {
    scheduler.add(() = > timeout(time)).then(() = > {
      console.log(time, order)
    })
  }
Copy the code

Attach the complete code

class Scheduler {
constructor(count) {
  this.list = []
  this.maxCount = count
  this.count = 0
}
add(task) {
  return new Promise(resolve= > {
    this.list.push(() = > {
      resolve(Promise.resolve(task()).then(s= > {
        this.count--
        this.start()
        return s
      }))
    })
    this.start()
  })
}
start() {
  console.log(this.count)
  if(this.count < this.maxCount) {
    this.count++
    this.list[0] && this.list[0] ()this.list.shift()
  }
}
}

let scheduler = new Scheduler(5)
let timeout = (time) = > {
return new Promise(resolve= > {
  setTimeout(resolve, time)
})
}

let addTask = function addTask(time, order) {
scheduler.add(() = > timeout(time)).then(() = > {
  console.log(time, order)
})
}

addTask(5000.'1')
addTask(1100.'2')
addTask(2200.'3')
addTask(3300.'4')
addTask(3300.'5')
addTask(3300.'6')
addTask(3300.'7')
addTask(2200.'8')
Copy the code

Retry the function

function retry(fun, count) {
  if(count === 0) return
  let val = fun()
  if(val > 3) {
    return val
  } else {
    return retry(fun, --count)
  }
}

function random() {
  return Math.random() * 5
}
console.log(retry(random, 5))
Copy the code

This problem looks very simple now, but at that time the estimate is different, the train of thought is misunderstood, uncomfortable