I met these two function programming questions in the interview yesterday, but damn it, I had no idea at all (sad)
-
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
-
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