We often use promises to perform asynchronous operations in projects, but do we really understand promises? What apis does Promise have? How to write Promises by hand? With these questions in mind, I’ve put together some information about promises

What is a promise

Promise is an asynchronous programming solution with three states: Pending, Resolved and Rejected. When the state of a promise changes from Pending to Resolved or Rejected, The corresponding method is executed. Once the state has changed, there is no return

What problems does promise solve

  1. Callback hell Multiple callbacks nested with each other resulting in difficult code maintenance and bloated code
  2. Multiple concurrent requests are supported
  3. Solve unreadable code problems
  4. Promise only has one resolution to resolve trust issues in the code

What other solutions are there besides Promise

  • async await
  • Generator
  • setTimeout

setTimeout

What setTimeout really does is add an event to an existing event in the “task queue”, specifying that a piece of code should be executed at a specified time. SetTimeout Adds an Event that will be executed in the next Event Loop.

Generators/yield

Generators Unlike traditional functions, a Generator’s greatest feature is that it can control the execution of functions. Here is a code to understand

function* foo(x) { let y = 2 * (yield (x)) let z = yield (y / 3) return (x + y + z) } let it = foo([1, 2]) console.log(it.next()); //6 // console.log(it.next(12)); // Invalidate the last execution result. 12 Yield console.log(it.next());Copy the code

async/await

Async /await is implemented based on promises, so it is also non-blocking. Async /await looks cleaner, and async/await makes asynchronous code look more like synchronous code.

The use of the promise

  1. Create a Promise instance object
  2. Use the then method to specify the resolved and Rejected state callback functions
  3. Use the catch method to specify the callback function for the Rejected state

The shortcoming of promise

  1. Once a promise is implemented, it cannot be canceled
  2. The promise error cannot be caught externally
  3. Externally, it’s hard to detect how promises work internally

Common APIS for Promise

Promise.then(): Gets the correct result of the asynchronous task

Promise.catch(): Gets an exception

Promise.finally(): Executes regardless of success or failure

Promise.all(): Process multiple asynchronous tasks concurrently, and get results only after all tasks are completed

Promise.race(): Handles multiple asynchronous tasks concurrently, and gets results as long as one task completes

A Promise question

The red light is on once every 3 seconds, the green light is on once every 1 second, and the yellow light is on once every 2 seconds. How do I make three lights turn on again and again? (Implement with Promise)

function red() {
    console.log("red");
}
function green() {
    console.log("green");
}
function yellow() {
    console.log("yellow");
}
const light = function (timer, cb) {
    return new Promise(resolve= > {
        setTimeout(() = > {
            cb()
            resolve()
        }, timer)
    })
}
const step = function () {
    Promise.resolve().then(() = > {
        return light(3000, red)
    }).then(() = > {
        return light(2000, green)
    }).then(() = > {
        return light(1000, yellow)
    }).then(() = > {
        return step()
    })
}

step();
Copy the code

Write a Promise

In just six steps, you will realize the Promise principle – Nuggets (juejin)

// Determine the three states of Promise
const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
class myPromise {
constructor(executor) {
/ / success
this.value = null
/ / fail
this.reason = null
// Determine the initial state
this.state = PENDING
this.onFulfilledCallbacks = []
this.onRejectedCallbacks = []
// Initialize this
this.resolve = this.resolve.bind(this)
this.reject = this.reject.bind(this)
try {
executor(this.resolve, this.reject)
} catch (error) {
this.reject(error)
}
}
resolve(value) {
if (this.state ! == PENDING)return
// Get the parameter modification status
this.value = value
this.state = FULFILLED
this.onFulfilledCallbacks.map(cb= > cb(value))
}
reject(reason) {
if (this.state ! == PENDING)return
// Get the parameter modification status
this.reason = reason
this.state = REJECTED
this.onRejectedCallbacks.map(cb= > cb(reason))
}
then(onFulfilled, onRejected) {
const that = this
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : v= > v
onRejected = typeof onRejected === 'function' ? onRejected : err= > {
throw err
}
return new myPromise((resolve, reject) = > {
if (that.state === FULFILLED) {
setTimeout(() = > {
const result = onFulfilled(that.value);
if (result instanceof myPromise) {
result.then(
value= > {
resolve(value)
},
reason= > {
reject(reason)
}
)
} else {
resolve(result)
}
}, 0)}else if (that.state === REJECTED) {
setTimeout(() = > {
onRejected(that.reason)
}, 0)}else {
that.onFulfilledCallbacks.push(onFulfilled)
that.onRejectedCallbacks.push(onRejected)
}
})
}
}
Copy the code