Daily study notes, including ES6, Promise, Node.js, Webpack, HTTP principles, Vue family buckets, and possibly more Typescript, Vue3, common interview questions, etc.

Promise static methods

This article only records the implementation, not the usage.

We encapsulate A promise library that conforms to the PROMISE /A+ specification. Now let’s implement the static methods contained in the library.

Promise.resolve()

New Promise((resolve,reject)=>{resolve(100)})

Implementing this method is as simple as adding static methods to our well-implemented class libraries.

static resolve(val) {
  return new Promise((resolve, reject) = > {
    resolve(val)
  })
}
Copy the code

Promise.reject()

New Promise((resolve,reject)=>{reject(100)})

Implementing this method is also very simple, adding static methods to our well-implemented class libraries.

static reject(val) {
  return new Promise((resolve, reject) = > {
    reject(val)
  })
}
Copy the code

Promise.catch()

Promise.catch() is equivalent to.then(null, () => {})

So we can implement this method directly in the class library

catch (errorFn) {
  return this.then(null, errorFn)
}
Copy the code

Promise.all()

The following code exists

let promise1 = new Promise((resolve, reject) = > {resolve(100)})
let promise2 = new Promise((resolve, reject) = > {reject(200)})
let promise3 = new Promise((resolve, reject) = > {resolve(300)})
let promise4 = new Promise((resolve, reject) = > {resolve(400)})
Promise.all([promise1, promise2, promise3, promise4]).then(result= > {
  console.log(result);
}).catch(reason= > {
  console.log(reason); / / 200
})
Copy the code

There are multiple Promise instances, and their success results are not executed until all of them have been executed. When one of the instances fails, the entire promise. all result becomes a failure.

Based on the above conclusion, we can try to implement promise.all ()

static all(promises) {
  return new Promise((resolve, reject) = > {
    let results = []
    let times = 0
    const processSuccess = (index, val) = > {
      results[index] = val;
      if (++times === promises.length) {
        resolve(results)
      }
    }
    for (let i = 0; i < promises.length; i++) {
      let p = promises[i];
      if (p && typeof p.then === 'function') {
        p.then(result= > {
          processSuccess(i, result)
        }, reject)
      } else {
        processSuccess(i, p)
      }
    }
  })
}
Copy the code

Promise.race()

There are multiple Promise instances, and when the first one returns the result, the entire promise.race is finished.

static race(promises) {
  return new Promise((resolve, reject) = > {
    for (let i = 0; i < promises.length; i++) {
      let p = promises[i]
      if (p && typeof p.then === 'function') {
        p.then(resolve, reject)
      } else {
        resolve(p)
      }
    }
  })
}
Copy the code

The actual case

In practice, promise.race () can be used to handle images that fail to load or scripts that time out.

function wrap(p1) {
  let abort;
  let p = new Promise((resolve, reject) = > {
    abort = reject;
  })
  let p2 = Promise.race([p, p1]); // Combine the custom error Promise with your own Promise
  p2.abort = abort;
  return p2;
}
/ / use
let p1 = new Promise(...).// Promise asynchronous operations to be processed
let promise = wrap(p1);
promise.then(result= >{... },reason= >{... })// A callback for success or failure
// Timeout processing
setTimeout(() = > {
  promise.abort(); // Set the timeout period to 60s
}, 60000);
Copy the code

Wrap a wrap() function that takes an array of promises. We set a property called ABORT in the function. Abort takes the reject method in a new Promise.

So abort in wrap acts like an interrupt button.

Promise.finally()

This method is executed whether the Promise succeeds or fails, and it does not accept arguments passed by the preceding.then method.

After execution, the code continues to execute (subsequent.then methods continue to execute), and if a new Promise is returned in.finally(), the Promise will not be passed except for a failed result.

finally(onFinally) {
  return this.then(
    // Promise.resolve can wait for the Promise in the callback to finish executing
    value= > Promise.resolve(onFinally()).then(() = > value),
    reason= > Promise.resolve(onFinally()).then(() = > {
      throw reason
    })
  )
}
Copy the code

Promise.allSettled

There are multiple Promise instances, and when all of them are completed, all the results are returned, whether they are true or false. So he won’t go.

Promise.any

There are multiple Promise instances, and if one of them succeeds, the successful result is taken (the first successful value is taken), and the failure result is taken only if all of them fail.

promisify

In my last article, I encapsulated a Promise asynchronous function, readFile, in a cumbersome way.

const fs = require('fs');
function readFile(path, encoding) {
  return new Promise((resolve, reject) = > {
    fs.readFile(path, encoding, (err, data) = > {
      if (err) reject(err)
      resolve(data)
    })
  })
}
readFile('./a.txt'.'utf8').then(result= > { console.log(result) })
Copy the code

Is there an easy way to do that? The answer is yes.

Node’s built-in util module has a Promisify method that magically turns asynchronous functions into promises.

const fs = require('fs');
const util = require('util');
let readFile = util.promisify(fs.readFile) // Omitted its own encapsulation process
readFile('./a.txt'.'utf8').then(result= > { console.log(result) })
Copy the code

Now we can try our hand at how it works

function promisify(readFile) {
  return function (. args) {
    return new Promise((resolve, reject) = >{ readFile(... args,(err, data) = > {
        if (err) return reject(err)
        resolve(data)
      })
    })
  }
}
Copy the code

So let’s write a promisify method by hand.

This article is created by Mo Xiaoshang, if there are any problems and flaws in the article, you are welcome to correct and communicate. You can also follow my personal site, blog garden and nuggets, and I will upload my posts to these platforms as soon as they are produced. Finally, thank you for your support!