Understanding Promise Objects in JavaScript

foreword

Callback functions are used when handling asynchronous operations. The more callback functions are used, the nested callback functions will form a callback hell. At this time, the code structure will become ugly and more and more difficult to maintain.

setTimeout(function() {
    
    
	console.log('第一层');
	setTimeout(function() {
    
    
		console.log('第二层');
		setTimeout(function() {
    
    
			console.log('第三层');
			setTimeout(function() {
    
    
				console.log('第四层');
			}, 1000)
		}, 1000)
	}, 1000)
}, 1000)

We can use Promise to solve this problem

Promise

PromiseObjects are used to represent the eventual completion (or failure) of an asynchronous operation and its result value.

describe

A Promise object represents a proxy whose value is not necessarily known when the promise is created. It allows you to associate the final success return value or failure reason of an asynchronous operation with the corresponding handler. This allows asynchronous methods to return values ​​like synchronous methods: instead of returning the final value immediately, an asynchronous method returns a promise to deliver the value to the user at some point in the future.

A Promise must be in one of the following states:

  • Pending: The initial state, neither honored nor rejected.
  • Fulfilled: means the operation completed successfully.
  • Rejected: means the operation failed.

Constructor

Promise(): Create a new Promise object. This constructor is mainly used to wrap functions that haven't added promise support yet.

Create a Promise instance object:

const done = true
const promise = new Promise((resolve, reject) => {
    
    
  if (done) {
    
    
    const str = '已兑现'
    resolve(str)
  } else {
    
    
    const str = '已拒绝'
    reject(str)
  }
})
console.log(promise)

done is true, output the following:

insert image description here

done is false, output the following:

insert image description here
At this time, the Promise object is returned, and the content cannot be used directly, and 实例方法the content can be obtained through .

instance method

Promise.prototype.then(): Add a fulfilled state callback function for the promise
Promise.prototype.catch(): Add a rejected state callback function for the promise
Promise.prototype.finally(): Add a fulfilled and rejected state callback function for the promise. When the promise ends, regardless of whether the result is fulfilled or rejected, The specified callback function will be executed.

Example:

const done = true
const promise = new Promise((resolve, reject) => {
    
    
  if (done) {
    
    
    const str = '已兑现'
    resolve(str)
  } else {
    
    
    const str = '已拒绝'
    reject(str)
  }
})
promise.then(res => {
    
    
	// 返回状态为 resolved
	console.log(res);
}).catch(err => {
    
    
	// 返回状态为 rejected
	console.log(err);
}).finally(() => {
    
    
	// 返回状态为 (resolved 或 rejected)
	console.log('finally');
})

As shown above, when done is true , then()the method output is triggered '已兑现', and when done is false, catch()the method is triggered to capture error output '已拒绝', whichever finally()method will eventually be triggered.

A more common example is a technique called Promisifying, which uses classic JavaScript functions that accept callbacks and make them return promises:

// nodejs示例
const fs = require('fs')

const getFile = (fileName) => {
    
    
  return new Promise((resolve, reject) => {
    
    
    fs.readFile(fileName, (err, data) => {
    
    
      if (err) {
    
    
        reject(err)  // 调用 `reject` 会导致 promise 失败,无论是否传入错误作为参数,
        return        // 且不再进行下去。
      }
      resolve(data)
    })
  })
}

getFile('/etc/passwd')
.then(data => console.log(data))
.catch(err => console.error(err))

// axios请求示例,axios返回的就是Promise对象
import axios from 'axios'

const function getList() {
    
    
  return axios({
    
    
    url: 'http://xxx/api/getList',
    method: 'get'
  })
}

getList()
.then(res => console.log(res))
.catch(err => console.error(err))

Promise was standardized and introduced ES2015in , and added in ES2017 async/await, the above example can be further optimized

// api.js
import axios from 'axios'

export function getList() {
    
    
  return axios({
    
    
    url: 'http://xxx/api/getList',
    method: 'get'
  })
}

// App.vue
import {
    
     getList } from './api.js'

created() {
    
    
  this.init()
}
methods: {
    
    
  async init() {
    
    
    // await 是一个修饰符,只能放在async定义的函数内
    // 可以获取Promise中返回的内容(resolve或reject的参数)
    // 且取到值后语句才会往下执行
    const res = await getList()
    console.log(res)
  }
}

static method

Promise.resolve(value): Returns a Promise whose state is determined by the given value. If value is a Promise object, the state will be determined according to the final state of value; otherwise, the state of the returned Promise object is fulfilled, and the value is passed to the corresponding then method.
Promise.reject(reason): Return a Promise object whose status is rejected, and pass the given failure information to the corresponding handler function.

Example:

const status = response => {
    
    
  if (response.status >= 200 && response.status < 300) {
    
    
    return Promise.resolve(response)
  }
  return Promise.reject(new Error(response.statusText))
}

fetch('/todos.json')
  .then(status)    // 注意,`status` 函数实际上在这里被调用,并且同样返回 promise,
  .then(data => {
    
    
    console.log('res:', data)
  })
  .catch(error => {
    
    
    console.log('请求失败', error)
  })

Promise.all(iterable): Wait until all promise objects succeed or any promise fails, and it is used when multiple different promises need to be synchronized

Example:

const f1 = fetch('/something.json')
const f2 = fetch('/something2.json')

Promise.all([f1, f2])
  .then(res => {
    
    
    console.log('结果的数组', res)
  })
  .catch(err => {
    
    
    console.error(err)
  })

ES2015 destructuring assignment syntax also works:

Promise.all([f1, f2]).then(([res1, res2]) => {
    
    
  console.log('结果', res1, res2)
})

Promise.race(iterable): wait until the status of any promise becomes finalized (fulfilled or rejected)

Example:

const first = new Promise((resolve, reject) => {
    
    
  setTimeout(resolve, 500, '第一个')
})
const second = new Promise((resolve, reject) => {
    
    
  setTimeout(resolve, 100, '第二个')
})

Promise.race([first, second]).then(result => {
    
    
  console.log(result) // 第二个
})

Promise.allSettled(iterable): wait until all promises have been finalized (every promise has been fulfilled or rejected), if you want to know the result of each promise

Example:

const promise1 = Promise.resolve(3);
const promise2 = new Promise((resolve, reject) => setTimeout(reject, 100, 'foo'));
const promises = [promise1, promise2];

Promise.allSettled(promises).then((results) => results.forEach((result) => console.log(result.status)));

// expected output:
// "fulfilled"
// "rejected"

Guess you like

Origin blog.csdn.net/sunddy_x/article/details/125301431