首页 > 其他分享 >js基础之Promise详解

js基础之Promise详解

时间:2023-05-25 11:24:13浏览次数:54  
标签:resolve console log js 详解 Promise reject promise

1. 是什么

Promise是一种异步编程的解决方案,用于处理异步操作并返回结果。
主要作用是解决回调函数嵌套(回调地狱)的问题,使异步操作更加清晰、易于理解和维护。

2. 怎么用

Promise有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。当一个Promise被创建时,它的状态为pending。当异步操作完成并成功时,Promise的状态会变为fulfilled,并返回一个结果。当异步操作失败时,Promise的状态会变为rejected,并返回一个错误信息。

基本语法

// 创建一个promise
let promise = new Promise(function(resolve, reject) {// 异步操作if (异步操作成功) {resolve(value); // 将异步操作的结果传递给Promise对象,状态变为fulfilled} else {reject(error); // 将异步操作的错误信息传递给Promise对象,状态变为rejected}
});promise.then(function(result) {// 异步操作成功时的处理代码
}).catch(function(error) {// 异步操作失败时的处理代码
});

常用方法

1.then

then中一般传入两个参数(函数),第一个对应resolve成功的回调,第二个对应reject失败的回调,如下

function onResolved(res) {
  console.log("resolved-" + res); // resolved-成功了
}
function onRejected(err) {
  console.log("rejected-" + err); // rejected-失败了
}
new Promise((resolve, reject) => {
  resolve('成功了');// reject('失败了')
}).then(onResolved, onRejected);

then的第二个参数就等同于catch方法,但是需要注意

  • Promise内部报错,reject抛出错误后,then的第二个参数和catch方法都存在的情况下,只有then的第二个参数能捕获到,如果then的第二个参数不存在,catch方法会捕捉到
  • catch不仅捕捉promise中抛出的错误,还会捕捉前面then中的错误

2.catch

捕捉promise错误函数,和then的第二个参数(函数)作用一样,处理错误,由于Promise抛出错误具有冒泡性质,能够不断传递,会传到catch中,所以一般来说所有错误处理放在catch中,then中只处理成功的,同时catch还会捕捉then中第一个参数(函数)抛出的异常

new Promise((resolve, reject) => {
  reject();
}).catch((err)=> {
  console.log(err)
});

3.finally

  • finally 方法没有参数,也不会改变 Promise 的状态,它只是在 Promise 结束时提供了一个通知机制,让我们可以在 Promise 结束后执行一些清理工作(比如操作文件的时候关闭文件流)。
  • Promise对象的finally()方法用于在Promise成功或拒绝时使用
  • 不管promise最后的状态,在执行完then或catch指定的回调函数以后,都会执行finally方法指定的回调函数,它可以防止Promise的then()和catch()方法中的代码重复。
// 栗子1
function onFinally() {
  console.log('结束');
}
new Promise((resolve, reject) => {}).finally(onFinally);

// 栗子2
let promise = new Promise((resolve,reject) => {
    resolve('resolve')
})
promise.then((res) => {
    console.log(res)
}).catch((err) => {
    console.log(err)
}).finally(()=> {
    console.log('this finally')
})
// resolve
// this finally

4.all

接受一个具有Iterable接口的类型,如数组,Map,Set,传入多个promise,
每一个promise执行成功resolve,最后才执行成功(返回一个Promise实例),进入then,否则失败进入catch

function p1() {
  var promise1 = new Promise(function (resolve, reject) {
      console.log("p1的第一条输出语句");
      resolve("p1完成");
  });
  return promise1;
}
function p2() {
  var promise2 = new Promise(function (resolve, reject) {
      console.log("p2的第一条输出语句");
      setTimeout(() => {
        console.log("p2的第二条输出语句");
        resolve("p2完成");}, 2000);
      });
      return promise2;
  }
}
function p3() {
  var promise3 = new Promise(function (resolve, reject) {
      console.log("p3的第一条输出语句");
      resolve("p3完成");
  });
  return promise3;
}
Promise.all([p1(), p2(), p3()]).then(function (data) { 
  console.log(data);
});// 输出
// p1的第一条输出语句;
// p2的第一条输出语句;
// p3的第一条输出语句;
// p2的第二条输出语句[("p1完成", "p2完成", "p3完成")];
var p1 = new Promise((resolve, reject) => {
  setTimeout(resolve, 1000, 'one');
});
var p2 = new Promise((resolve, reject) => {
  setTimeout(resolve, 2000, 'two');
});
var p3 = new Promise((resolve, reject) => {
  setTimeout(resolve, 3000, 'three');
});
var p4 = new Promise((resolve, reject) => {
  setTimeout(resolve, 4000, 'four');
});
var p5 = new Promise((resolve, reject) => {
  reject('reject');// setTimeout(resolve, 5000, 'five');
});
Promise.all([p1, p2, p3, p4, p5]).then(values => {
  console.log(values); // [ 'one', 'two', 'three', 'four', 'five' ]
}, reason => {
  console.log(reason) // reject
});

5.allSettled

接受一个具有Iterable接口的类型,如数组,Map,Set,传入多个promise,
每个promise状态改变成fulfilled或者rejected之后返回,返回的是一个数组对象,对象中有状态status和每一项的返回结果value

Promise.allSettled([p1, p2, p3, p4, p5]).then(values => {
  console.log(values);
}, reason => {console.log(reason)
});
// [
//   { status: 'fulfilled', value: 'one' },
//   { status: 'fulfilled', value: 'two' },
//   { status: 'fulfilled', value: 'three' },
//   { status: 'fulfilled', value: 'four' },
//   { status: 'rejected', reason: 'reject' }
// ]

6.race

以快为准,数组中所有的promise对象,有一个先执行了何种状态,该对象就为何种状态,并执行相应函数
接受一个具有Iterable接口的类型,如数组,Map,Set,传入多个promise,
其中有一个promise返回了,不管是fulfilled或者rejected,直接返回这个promise的结果

function p1() {
  var promise1 = new Promise(function (resolve, reject) {
      console.log("p1的第一条输出语句");
      resolve("p1完成");
  });
  return promise1;
}
function p2() {
  var promise2 = new Promise(function (resolve, reject) {
      console.log("p2的第一条输出语句");
      setTimeout(() => {
        console.log("p2的第二条输出语句");
        resolve("p2完成");
      }, 2000);
  });
  return promise2;
}
function p3() {
  var promise3 = new Promise(function (resolve, reject) {
    console.log("p3的第一条输出语句");
    resolve("p3完成");
  });
  return promise3;
}
Promise.race([p1(), p2(), p3()]).then(function (data) {
  console.log(data);
});// 输出
// p1的第一条输出语句
// p2的第一条输出语句
// p3的第一条输出语句
// p1完成

7.any

接受一个具有Iterable接口的类型,如数组,Map,Set,传入多个promise,
当传入的任何一个promise成功的时候,不管其他是否成功或者失败,会把成功的那个promise返回

如果传入的是一个空的数组(Map,Set),返回一个已失败状态的promise,如下

注意
Promise的以上方法都属于 微任务。当Promise状态变为已解决(resolved)或被拒绝(rejected)时,这些方法会产生微任务。这些微任务会在主线程空闲时按照顺序依次执行。

3. 有什么问题

  • 首先,无法取消 Promise,一旦新建它就会立即执行,无法中途取消。
  • 其次,如果不设置回调函数,Promise 内部抛出的错误,不会反应到外部。
  • 第三,当处于 Pending 状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。

标签:resolve,console,log,js,详解,Promise,reject,promise
From: https://www.cnblogs.com/axingya/p/17430614.html

相关文章

  • Jquery Deferred 对比 Promise
    javascript处理异步逻辑有多种方式,这里只对比JQuery的Deferred和ES6的Promise。场景是判断网页中所有图片是否加载完(加载异常404也算加载完毕)。JQuery Deferred方式1varimgdefereds=[];2$('img').each(function(){3vardfd=$.Deferred();45$......
  • jsdom, proxy对象(补环境神器)以及抠代码总结的问题
    jsdomconstjsdom=require('jsdom')const{JSDOM}=jsdomconstfs=require('fs')options={url:'http://match.yuanrenxue.com/match/2',referrer:'http://match.yuansrenxue.com/match/2',......
  • 时间不等人,但 Moment.js 可以等你解决时间问题!
    前言一直以来,处理时间和日期的JavaScript库,选用的都是Moment.js。它的API清晰简单,使用方便灵巧,功能还特别齐全。我是Moment.js的重度使用者。凡是遇到时间和日期的操作,就把Moment.js引用上。简介Moment.js是一款常用于JavaScript日期时间处理的代码库,它能够解析、验证、操作以......
  • N5、seq2seq详解
    ......
  • 关于对Promise 以及async的理解!
    为了解决Promise.then和.catch看起来比较乱以及写起来比较麻烦的问题,可以用async配合await来调用Promise实现异步操作。代码的写法和同步有点类似。例如:asyncfunctionget(url){try{letresp=awaitfecth(url);returnresp.json();}catch(e){//出错了}}用a......
  • C++之constexpr详解
    constexpr表达式是指值不会改变并且在编译过程就能得到计算结果的表达式。声明为constexpr的变量一定是一个const变量,而且必须用常量表达式初始化:constexprintmf=20;//20是常量表达式constexprintlimit=mf+1;//mf+1是常量表达式constexprintsz=size();//之后......
  • 01-Node.js介绍
    01.Node.js是什么?pNode.js是一个基于V8JavaScript引擎的JavaScript运行时环境。也就是说:Node.js基于V8引擎来执行JavaScript的代码。V8引擎可以嵌入到任何C++应用程序中,无论是Chrome还是Node.js,事实上都是嵌入了V8引擎来执行JavaScript代码的。但需要注意的是:两者都不仅......
  • 02-Node.js的包管理工具
    00.代码共享方案模块化的编程思想,支持将代码划分成一个个小的、独立的结构。我们可以通过模块化的方式来封装自己的代码,将之封装成一个工具;这个工具我们可以让同事通过导入的方式来使用,甚至也可以分享给世界各地的程序员来使用;假如,我们要将某个工具分享给世界上所有的程序员......
  • js replace 和 replaceAll
    js中的replace方法和自定义replaceAll方法<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>String字符串测试</title></head><body><inputtype="submit"va......
  • 请求和响应——原生的JS实现方式
    请求和响应--原生的JS实现方式有时候我们不得不用原生方式去请求,而这又不常用,所以记录一下,方便下次直接使用。XMLHttpRequest用于在后台与服务器交换数据。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。//1.创建核心对象varxmlhttp;if(window.XMLHttpRe......