Promise的注意点, 以及相关题目

Promise详解-1:初识Promise 不懂Promise?看这篇教程就够了 阅读详情
前言

昨天面试去xiaoman, 提到了promise;
面对不断深入发问, 我脑子一片空白, 然后就想到了白云山;
我想怎么思考其他问题的时候没有这么思维活跃;

Promise 状态的不可逆性

Promise状态的一旦变成resolved或rejected时,Promise的状态和值就固定下来了,不论你后续再怎么调用resolve或reject方法,都不能改变它的状态和值。

var p1 = new Promise(function(resolve, reject){
  resolve("success1");
  resolve("success2");
});

var p2 = new Promise(function(resolve, reject){
  resolve("success");
  reject("reject");
});

p1.then(function(value){
  console.log(value);
});

p2.then(function(value){
  console.log(value);
});
// "success1"
// "success"
resolve或reject后面的代码会不会执行

当然会

then的第二个参数和catch

catch相当于then(null,function(err){ /*处理错误*/})的写法

// 写法一
new Promise((resolve)=>{
	foo.bar()
}).then(res=>{
	console.log(res)
},err=>{
	console.log(err)
})
// ReferenceError: foo is not defined
// 写法二
new Promise((resolve)=>{
	foo.bar()
}).then(res=>{
	console.log(res)
	kk()
}).catch(err=>{
	console.log(err)
})
// ReferenceError: foo is not defined

上面代码中,catch要好于then(null,err=>{})写法, catch可以捕获前面then方法执行中的错误,也更接近同步的写法(try/catch)。因此,建议总是使用catch方法,而不使用then方法的第二个参数。如下:

new Promise((resolve)=>{
	resolve(1)
}).then(res=>{
	console.log(res)
	kk()
}).catch(err=>{
	console.log(err)
})
// ReferenceError: kk is not defined
then/catch的链式调用

首先, 在new Promise中需要执行resolve或者reject改变状态,否则不会执行then方法, 像下面then就不会执行:

var p = new Promise(function(resolve, reject){
  return 1
});
p.then(function(value){              
  console.log(value);
  return value*2;
}).then(function(value){             
  console.log(value);
})
// Promise {<pending>}

在状态改变后, then方法返回一个新的Promise对象,因此可以通过链式调用then方法.
catch也可以链式调用, 因为catch相当于then(null,err=>{})

函数的返回值将被用作创建then返回的Promise对象, 有如下情况:

  • return 一个同步的值(当没有返回时,默认返回undefined),then方法将返回一个resolved状态的Promise对象,Promise对象的值就是这个返回值。
  • return 一个 Promise,then方法将根据这个Promise的状态和值创建一个新的Promise对象返回。
  • throw 一个同步异常,then方法将返回一个rejected状态的Promise, 值是该异常。
var p = new Promise(function(resolve, reject){
  resolve(1);
});
p.then(function(value){               //第一个then
  console.log(value);
  return value*2;
}).then(function(value){              //第二个then
  console.log(value);
}).then(function(value){              //第三个then
  console.log(value);
  return Promise.resolve('resolve'); 
}).then(function(value){              //第四个then
  console.log(value);
  return Promise.reject('reject');
}).then(function(value){              //第五个then
  console.log('resolve: '+ value);
}, function(err){
  console.log('reject: ' + err);
})
1
2
undefined
"resolve"
"reject: reject"

再写一个return返回promise的例子:

var a = new Promise(resolve=>{
	setTimeout(()=>{
		resolve('5s later')
	},5000)
})
var p = new Promise(function(resolve, reject){
  resolve(1);
});
p.then(function(value){               //第一个then
	console.log(1)
  	return a
}).then(function(value){              //第二个then
  console.log(value);
})


// 1
// Promise {<pending>}
// 5s later
Promise.resolve()

Promise.resolve()(注意,是Promise.resolve(),而不是new Promise中的resolve)可以接收一个值或者是一个Promise对象作为参数。
当参数是普通值时,它返回一个resolved状态的Promise对象;
当参数是Promise对象时,对象的值就是这个参数;
下面的例子可以看到p1,p2是相等的

let p1 = Promise.resolve(1)
let p2 = Promise.resolve(p1)
p1 === p2
// true
then拿到数据发现不合适, 怎么触发catch

throw new Error()抛出错误. 或者 Promise.reject()

resolve和reject

当resolve的参数是一个Promise对象时,resolve会"拆箱"获取这个Promise对象的状态和值,但这个过程是异步的。
即最后的状态是根据传入的promise对象的状态确定的;
如下: 执行的是resolve(a), 但是a5秒后返回的状态是rejected,所以会执行rejected回调

var a = new Promise((resolve,reject)=>{
	setTimeout(()=>{
		reject('error')
	},5000)
})
var p = new Promise(function(resolve, reject){
  	var b = resolve(a)
	console.log(a === b)
});
p.then(function(value){              
	console.log('success')
},function(err){              
	console.log(err)
	return err
})
// false
// Promise {<pending>}
// error

但是, reject方法不同, reject方法不存在拆箱等待, 而是直接将传入的promise对象传入下个阶段, 如下

var a = new Promise((resolve,reject)=>{
	setTimeout(() => {
		reject('error after 5s')
	},5000)
})

var p = new Promise(function(resolve, reject){
  	reject(a)
})

p.then(function(value){              
	console.log('success')
}).catch(err1=>{                  // 第一个 catch 
	console.log('fail: ' + err1)
	return err1
}).catch(err2=>{                  // 第二个 catch 
	console.log(err2)
	return 1
}).then(res=>{
	console.log(res)
})

// fail: [object Promise]
// Promise {<pending>}
// error after 5s
//  1

可以看到, p中reject了a, 直接把a传到了第一个 catch, 第一个catch中, 打印出来参数, 就是promise对象a .
在 第一个catch中return err1, 等待5秒后a变成rejected状态, 触发第二个 catch , 捕获到结果error after 5s,
最后catch 可以继续链式调用, 返回1, 相当于resolve(1), 最后then打印出1.

promise中出现异常, promise外的后面的代码会执行吗

会, Promise 内部的错误不会影响到 Promise 外部的代码,通俗的说法就是“Promise 会吃掉错误”。

new Promise(function(resolve, reject){
  resolve(x+1);
});
console.log(333)
// 333
// Uncaught (in promise) ReferenceError: x is not defined
promise.all
let a = new Promise(resolve=>{setTimeout(()=>{resolve(111)},3000)})
let b = new Promise(resolve=>{setTimeout(()=>{resolve(222)},1000)})
let c = new Promise(resolve=>{setTimeout(()=>{resolve(333)},100)})

Promise.all([b,a,c]).then(res=>{
	console.log(res)

})
// 结果数组也是顺序的
// [222, 111, 333]
let a = new Promise(resolve=>{setTimeout(()=>{console.log('haha');resolve(111);},3000)})
let b = new Promise((resolve,reject)=>{setTimeout(()=>{reject(222)},1000)})
let c = new Promise(resolve=>{setTimeout(()=>{resolve(333)},100)})

Promise.all([b,a,c]).then(res=>{
	console.log(res)
}).catch(err=>{
	console.log(err)
})
只要有一个错误,就会catch该错误
// 222
// haha
Promise如何按顺序执行

有一个数组,数组元素是返回Promise对象的函数,怎样顺序执行数组中的函数,即在前一个数组中的Promise resolve之后才执行下一个函数?
…

  • 先生成数据, 下面代码执行完,生成10个函数组成的数组, 均返回promise对象
function createPromises(id) {
    return function () {
        return new Promise(resolve => {
            setTimeout(() => {
                console.log(id)
                resolve(id)
            }, 1000)
        })
    }
}
 
let list = []

for(let i = 0; i < 10; i++) {
    list.push(createPromises(i))
}
// (10) [ƒ, ƒ, ƒ, ƒ, ƒ, ƒ, ƒ, ƒ, ƒ, ƒ]
  • 递归法
// 递归调用
function promise_queue(list, i) {
    if (i >= 0 && i < list.length) {
        list[i]().then(() => {
            promise_queue(list, i + 1)
        })
    }
}
promise_queue(list, 0)
  • await
async function promise_queue(list) {
    let index = 0
    while (index >= 0 && index < list.length) {
        await list[index]()
        index++
    }
}
promise_queue(list)
  • Promise.resolve()
    初始状态是Promise.resolve(), then执行第一个, 并把下一个作为then的success函数(因为then返回一个promise的话, promise状态改变后, 才会执行下一个then)
function promise_queue(list) {
  var sequence = Promise.resolve()
  list.forEach((item) => {
    sequence = sequence.then(item)
  })
  return sequence
}

  • reduce
	list.reduce((pre,next)=>pre.then(next),Promise.resolve()); 
promise实现每隔一段时间执行一次函数, 执行n次 , 不用await

每隔interval毫秒, 执行一次fn函数, 执行time次:

function interval(fn, interval, time){
	 let f = () => new Promise(resolve=>{
		setTimeout(()=>{
			fn()
			resolve()
		},interval)
	})
	let a = Promise.resolve()
	for(let i = 0; i< time; i++){
		a = a.then(f)
	}
}
最详细的Promise相关源码实现 写这篇文章的目的是解剖Promise源码,起因也是最近秋招被问到了让手写Promise,另外在网上看到的Promise源码或多或少有些小问题,也就是没有完全遵循Promise/A+规范。 代码会完全使用ES6语法,主要分以下几个模块: 整体分析(为代码书写铺路) 实现初版(构造函数大致功能亿完善) 支持异步和链式调用(完善then方法) 实现catch方法 实现Promise.resolve() 实现Promise.reject() 实现Promise.all() 实现Promise.race() 一、 阅读详情

相关推荐

若依开源框架(分离版)在人大金仓数据库下使用

对于甲方业务特殊要求,使用国产化数据库人大金仓,作为项目主要存储。这里以若依开源框架整合人大金仓为例,演示如何在真实项目中引入人大金仓。

🐱喵测实验室 5942

Promise总结

实例方法: then 调用then如果有返回值,返回的是一个新的Promise实例,隐藏可以使用链式写法,继续then下去 catch 异常捕获 静态方法: all 将多个Promise实例转换成一个Promise实例,如果不是则先调用resolve将参数转换成Promise实例,所有的状态都变成Fulfilled,才会返回给回调,但是有一个Rejected就会返...

pgLi 1786

深入解析Buck开关电源中的死区时间设计及其对系统性能的影响

本文深入解析了Buck开关电源中死区时间的设计原理及其对系统性能的关键影响。死区时间通过防止上下管同时导通来避免穿通电流,确保系统安全。文章详细探讨了其工作机制、设置时的效率与安全权衡,以及不当设置对效率、稳定性和EMI的连锁反应,并提供了基于实测的调试方法与实战案例。

Apple的专栏 1130

实现一个TS版,符合 Promise/A+规范的 Promise

本文授权转载自:Col0ring,http://juejin.cn/post/6886360224308035598,主旨:本文使用 typescript,根据类型定义从零开始实现了一个 ...

zz_jesse的博客 1447

PCAN-Explorer5使用教程

在PCAN中新建工程,导入DBC文件(右键apply),导入采集的数据选择对应的CAN通道点击红框中的标记可选择想要查看的信号在plot界面跳出属性,可调整信号显示的样式和最大最小值调出cursor,选择需要观测的变量,选中右键style——Period 可显示间隔时间增加cursor,可观测多个变量。

weixin_43997043的博客 6913

webapi .net core8.0配置使用Token权限认证

本人在网上找了很多版本,不是太复杂就是不行。

m0_74824592的博客 1760

JavaScript Promise | async / await

练习题 const promise = new Promise((resolve, reject) => { resolve('success1') reject('error') resolve('success2') }) promise .then((res) => { console.log('then: ', res) }) .catch((err) => { console.log('catch: ', err) }) /* 结

weixin_44240581的博客 244

FreeRTOS实战:如何避免HAL_Delay在高优先级中断中的坑(附TIM6配置指南)

本文深入剖析了在STM32 FreeRTOS项目中,于高优先级中断内调用HAL_Delay函数导致系统假死的根本原因——SysTick时基被FreeRTOS占用且优先级最低。文章提供了治本方案:通过配置TIM6作为独立且最高优先级的HAL时基,实现与FreeRTOS系统心跳的解耦,并附上详细的CubeMX配置与代码移植指南,确保系统实时性与稳定性。

weixin_29230059的博客 64

try和catch要写在promise回调里

return new Promise<void>((resolve,reject) => { try { throw new Error('error') resolve(); } catch (e) { console.log(e); } })

qq_45305088的博客 722

K8S搭建(centos)四、安装K8S

每个人都有惰性,但不断学习是好好生活的根本,共勉!

感谢阅读 2650

python 实现一个完整的基于Python的多视角三维重建系统,包含特征提取与匹配、相机位姿估计、三维重建、优化和可视化等功能

本文介绍了一个基于Python的多视角三维重建系统的实现,涵盖了特征提取与匹配、相机位姿估计、三维重建、优化和可视化等功能。首先,系统通过安装必要的库(如OpenCV、NumPy等)并加载图像数据,初始化相机参数。接着,系统使用SIFT、SURF或ORB算法提取图像特征点,并通过FLANN或BF方法进行特征匹配,应用Lowe's ratio test筛选优质匹配。该系统为后续的相机位姿估计和三维重建奠定了基础,能够从多视角图像中恢复三维场景结构。

huanghm88的专栏 615

promise介绍

promise

m0_62555895的博客 597

AD(十四)调用已有的PCB元件封装库

软件:Altium Designer 16 需要资料:已有的PCB原理图文件(.PCBDOC)或者PCB库文件(.PCBLIB)(来源文中细说) 调用已有的PCB元件封装库(一)从已有的PCB原理图文件(*.PCBDOC)中调用1、PCB原理图文件来源2、打开已有的PCB原理图文件(*.PCBDOC)3、生成PCB封装库4、复制封装到工程文件下的PCB库文件(*.PCBLIB)5、重名问题(二)从已有的PCB库文件(*.PCBLIB)中调用1、PCB库文件(*.PCBLIB)的来源2、打开已有的PCB库 (

Curnane0_0的博客 5083

JavaScript 之 promise

一文掌握 promise 用法~JavaScript 之 promise: 异步任务的处理 | Promise | Promise 解决异步处理 | Promise 的代码结构 | Executor | resolve 传递不同值的区别 | then 方法 | catch 方法 | finally 方法 | resolve 方法 | reject 方法 | all 方法 | allSettled 方法 | race 方法 | any 方法 | 手写 Promise

原来是有理数 1858

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

Promise相关知识点

使用 async 关键字定义一个异步函数,函数总是返回一个 Promise。return "数据获取成功";// 数据获取成功。

2501_92219249的博客 891

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

关于一道promise的诡异题目的理解

要解决的题目如下: Promise.resolve().then(() => { console.log(0); return Promise.resolve(4); }).then((res) => { console.log(res) }) Promise.resolve().then(() => { console.log(1); }).then(() => { console.log(2); }).then(() => {

hemanzi_17的博客 2969

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

promise的用法以及注意事项,看了这篇你就会了

是异步编程的一种解决方案: 从语法上讲,Promise是一个对象,从它可以获取异步操作的消息;Promise是一个构造函数,自己身上有reject,resolve,all,race这几个方法,原型上有then、catch等方法。将Promise的状态置为rejected,这样我们在then中就能捕捉到,然后执行“失败”情况的回调。以最先得到的结果为准,即使如果最先拿回来的是reject的结果,那么race就是reject的结果。好了,promise的常见用法就这些,下一篇我们来聊聊promise的源码!

xlei1123的博客 1163

第2集丨Promise 的两个注意点

调用resolve或reject并不会终结 Promise 的参数函数的执行。 ● 上面代码中,调用以后,后面的还是会执行,并且会首先打印出来。这是因为立即 的 是在本轮事件循环的末尾执行,总是晚于本轮循环的同步任务。 ● 一般来说,调用或以后,的使命就完成了,后继操作应该放到方法里面,而不应该直接写在或的后面。所以,最好在它们前面加上语句,这样就不会有意外。 ● 如果调用函数和函数时带有参数,那么它们的参数会被传递给回调函数。 ● 函数的参数通常是对象的实例,表示抛出的错误; ● 函数的参数除了正

秋堂主的博客 170

前端高频面试题之Promise相关方法

Promise一直是前端面试中的热点,下面给大家介绍下Promise的相关方法。调用时需要传入一个promise数组,我们称它为promiseArr,然后会返回一个新的Promise,我们把它称为p如果promiseArr中有一个Promise失败,则走入p的catch回调中,并拿到对应的错误对象。如果promiseArr里面全成功,则会走入p的then方法中,并能拿到之前传入的promiseArr对应的promise结果。race的意思是赛跑,哪个Promise跑的快,也就是哪个Promise。

程序员小寒的博客 668

ES6中 Promise 相关知识点、常见使用场景、以及案例

Promise 是 JavaScript 中解决异步编程的新方案,相比传统回调函数具有显著优势。它通过链式调用(.then())避免了回调地狱问题,使异步代码更易读和维护;同时支持统一错误捕获(.catch()),解决了多层回调中错误处理分散的痛点。Promise 有三种不可逆状态(Pending、Fulfilled、Rejected),状态转换由 resolve/reject 触发,决定了回调的执行时机。这种机制既保证了异步操作的顺序性,又确保了结果的可靠性,成为现代 JavaScript 异步编程的核心

qq_49581491的博客 880

Promise的用法和相关面试题整理

本篇文章的目的有三个: 第一,会用Promise 第二,能看懂别人写的Promise代码 第三,能够回答面试中大多数的promise相关问题

接着奏乐接着舞的博客 2263

Promise相关介绍

promise的使用

smart_dream 192

面试中Promise相关问题

结合bilibili和小米和阿里的面试题中出现的与Promise对象相关的问题自己试着做了一些回答,涉及的有以下几个问题。 详述Promise的异步机制? Promise有几种状态? Promise如何满足多个异步进程的同步顺序? Promise.all的用法 如何让Promise.all在抛出异常后依然有效? Promise.all与Promise.race的区别?应用场景? 1.Promi...

tomorrownan的博客 602

关于promise的相关知识

const p = new promise((resolve,reject)=>{console.log('111')}) p返回值就是一个promise实例。const a = new Promise((resolve,reject)=>{ resolve(10) }) // 返回成功的结果 通过.then来接收。a.then(res=>{console.log(res)},err=>{console.log(err)}) // err返回的是a实例对象失败的结果。

h960822的博客 1026

ES6 Promise的应用场景及注意事项

ES6 Promise的应用场景及注意事项 场景一: 通过接口1得到的结果为参数调用接口二,使用接口二得到的数据作为参数调用接口三,最后返回接口三的数据。代码如下: //模拟接口 let fakeInterface = (url, param) => { return new Promise((resolve, reject) => { setTimeout(() => { //模拟一个异步的接口 //想让哪个接口报错(走reject)就把inde

wallace_yang的博客 724

Promise相关知识

1.Promise简介 Promise是异步编程的一种解决方案,比传统的解决方案(回调函数和事件)更合理和更强大; 所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果; 具体表达: 从语法上来说: Promise是一个构造函数; 从功能上来说: promise对象用来封装一个异步操作并可以获取其结果(数据); 2.Promise对象的两个...

xp_xpxp的博客 330
上一篇: webpack相关
下一篇: Vue.set()
飞驰的地铁
博客等级 码龄11年 13粉丝 64原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值