异步编程promise
异步编程发展
异步编程经历了 callback、promise、async/await、generator四个阶段,其中promise和async/await使用最为频繁,而generator因为语法晦涩难懂,很少使用。
本文主要讲述promise如何使用。
promise语法
promise的三种状态
pending状态:
未调用resolve或者reject时候处于pending状态
fullfilled状态:
调用resolve后处于fullfilled状态
rejected状态:
调用reject后处于rejected状态。如果在pending状态时候,执行任务抛出错误,则变成reject状态。
promise对象的方法then、catch、all、race、allSettled
then
then方法不传参数
// 第一个promise
const p = new Promise(resolve => {
throw new Error('test'); // 抛出错误
});
// 第二个promise
p.then(
() => {} // 这里是状态变为fullfilled的回调函数
// 这里空着的,本应该填的是状态变为rejected的回调函数,所以不传递参数
)
// 第三个promise
.then(
data => console.log('resolve', data),
err => console.log('reject', err)
)
// 运行结果:reject Error: test
// 可见,第一个promise抛出的错误,即使第二个promise没有rejected回调函数,第三个promise的rejected回调函数依旧能接受到参数
// 结论:无论onFullfilled还是onRjected中,上一个promise不对参数进行处理,下一个promise进行处理
then方法回调不返回值
// 第一个promise
const p = new Promise(resolve => {
resolve('test')
});
// 第二个promise
p.then(() => {
() => {} // 状态变成fullfilled的回调函数,没有返回值
})
// 第三个promise
.then(
data => console.log('resolve', data),
err => console.log('reject', err)
)
// 运行结果:resolve undefined
// 第一个promise
const p = new Promise(() => {
throw new Error('error');
});
// 第二个promise
p.then(
() => {},
() => {} // 状态变成rejected的回调函数,没有返回值
)
// 第三个promise
.then(
data => console.log('resolve', data),
err => console.log('reject', err)
)
// 运行结果:resolve undefined
// 结论:无论onFullfilled还是onRjected中,then方法回调不返回值,状态都会变成fullfilled,走fullfilled的回调函数
then方法回调返回普通值
var p = new Promise(resolve => {
throw new Error('test');
});
p.then(
() => { return 'a' },
() => { return {b: 1} }
).then(
(data) => console.log("resolve", data),
(err) => console.log("reject", err)
);
// 运行结果:resolve {b: 1}
// 结论:无论onFullfilled还是onRjected中,then方法回调返回普通值,状态都会变成fullfilled,走fullfilled的回调函数
then方法回调返回promise
var p = new Promise(resolve => {
throw new Error('test');
});
p.then(
() => { return 'a' },
() => { return Promise.resolve('test') }
).then(
(data) => console.log("resolve", data),
(err) => console.log("reject", err)
);
// 运行结果:resolve test
// 结论:无论onFullfilled还是onRjected中,返回一个promise对象,则以该promise的任务和状态返回新的promise
then方法回调返回thenable对象
var p = new Promise((r) => {throw new Error('test')});
p.then(
() => ({then: function(resolvePromise, rejectPromise) {resolvePromise('resolvePromise')}}),
e => ({then: function(resolvePromise, rejectPromise) {rejectPromise('rejectPromise')}})
)
.then(
data => console.log('resolve', data),
e => console.log('reject', e)
);
// 运行结果:reject rejectPromise
// 结论:无论onFullfilled中还是onRejected中,返回一个thenable对象,则调用该对象的then方法,该then方法接收两个参数resolvePromise和rejectPromise。
// 如果then中调用了resolvePromise,则返回的promise状态置为fullfilled,如果then中调用了rejectPromise,或者then中抛出异常,则返回的Promise状态置为rejected。
// 在调用resolvePromise或者rejectPromise之前,返回的promise处于pending状态。
then方法回调抛出错误
无论onFullfilled中还是onRejected中,抛出错误,则以rejected为状态返回新promise。
catch
catch方法和then方法的reject回调用法相同,如果这时候任务处于rejected状态,则直接执行catch,catch的参数就是reject的reason;
var p = new Promise(resolve => {
throw new Error('test');
});
// catch写法
p.catch((err) => {
console.log(err);
})
// 两种写法等价
p.then(
undefined,
(err) => {
console.log(err);
}
)
all
Promise.all方法接收一个promise数组作为参数,返回一个promise,当参数的数组中的所有promise都resolve时候,返回的promise才会resolve;而若有一个参数的数组中的promise reject,返回的promise就会reject。
var p1 = Promise.resolve(1);
var p2 = new Promise(resolve => {
setTimeout(() => {
resolve(2);
}, 1000);
})
Promise.all([p1, p2])
.then(
([result1, result2]) => {console.log('resolve', result1, result2);}
)
// 运行结果:resolve 1 2
race
Promise.race接收一个promise数组作为参数,返回一个新的promise。当参数数组中其中一个promise resolve或者reject,返回的promise就相应地改变状态。
var p1 = Promise.reject(1);
var p2 = new Promise(resolve => {
setTimeout(() => {
resolve(2);
}, 1000);
});
Promise.race([p1, p2])
.then(
data => {console.log('resolve', data);},
e => {console.log('reject', e);}
);
// 运行结果:reject 1
allSettled
Promise.allSettled用于多个异步任务都结束(完成或者失败)时候,再执行后续任务的场景。
Promise.allSettled接收一个promise数组作为参数,返回一个promise。当参数数组中所有promise状态改变后,返回的promise变为fullfilled状态。
返回的promise的onFullfilled参数接收一个结果数组作为参数,数组对应Promise.allSettled传入的promise数组。结果数组每个元素是一个对象,格式固定:{status, value, reason},标识状态、resolve返回值、reject原因。
var p1 = Promise.reject(1);
var p2 = new Promise(resolve => {
setTimeout(() => {
resolve(2);
}, 1000);
});
Promise.allSettled([p1, p2])
.then(
data => {console.log('resolve', data);},
);
// 运行结果:resolve [{status: "rejected", reason: 1}, {status: "fulfilled", value: 2}]
异步编程promise的更多相关文章
- 简单实现异步编程promise模式
本篇文章主要介绍了异步编程promise模式的简单实现,并对每一步进行了分析,需要的朋友可以参考下 异步编程 javascript异步编程, web2.0时代比较热门的编程方式,我们平时码的时候也或多 ...
- 异步编程——promise
异步编程--promise 定义 Promise是异步编程的一个解决方案,相比传统的解决方法--回调函数,使用Promise更为合理和强大,避免了回调函数之间的层层嵌套,也使得代码结构更为清晰,便于维 ...
- 异步编程Promise/Deferred、多线程WebWorker
长期以来JS都是以单线程的模式运行的,而JS又通常应用在操作用户界面和网络请求这些任务上.操作用户界面时不能进行耗时较长的操作否则会导致界面卡死,而网络请求和动画等就是耗时较长的操作.所以在JS中经常 ...
- 简述异步编程&Promise&异步函数
前言:文章由本人在学习之余总结巩固思路,不足之前还请指出. 一.异步编程 首先我们先简单来回顾一下同步API和异步API的概念 1.同步API:只有当前的API执行完成之前,才会执行下一个API 例: ...
- AnjularJS异步编程 Promise和$q
Promise,是一种异步处理模式. js代码的函数嵌套会使得程序执行异步代码时很难调试.因为多重嵌套的函数无法确定何时触发回调. 如: funA(arg1,arg2,function(){ func ...
- es6异步编程 Promise 讲解 --------各个优点缺点总结
//引入模块 let fs=require('fs'); //异步读文件方法,但是同步执行 function read(url) { //new Promise 需要传入一个executor 执行器 ...
- 你所必须掌握的三种异步编程方法callbacks,listeners,promise
目录: 前言 Callbacks Listeners Promise 前言 coder都知道,javascript语言运行环境是单线程的,这意味着任何两行代码都不能同时运行.多任务同时进行时,实质上形 ...
- JavaScript异步编程 ( 一 )
1. 异步编程 Javascript语言的执行环境是"单线程"(single thread).所谓"单线程",就是指一次只能完成一件任务.如果有多个任务,就必须 ...
- JavaScript异步编程(1)- ECMAScript 6的Promise对象
JavaScript的Callback机制深入人心.而ECMAScript的世界同样充斥的各种异步操作(异步IO.setTimeout等).异步和Callback的搭载很容易就衍生"回调金字 ...
随机推荐
- python采集A站m3u8视频格式视频
基本开发环境 (https://jq.qq.com/?_wv=1027&k=NofUEYzs) Python 3.6 Pycharm 相关模块的使用 (https://jq.qq.com/?_ ...
- Linux修改默认ssh22端口
1.检查端口是否可用 使用下面的命令检查您想增加或修改的端口号是否被占用,执行命令后如果没有任何打印,说明这个端口没有被占用 netstat -lnp|grep 23456 2.修改配置文件 ssh配 ...
- 老掉牙的 synchronized 锁优化,一次给你讲清楚!
我们都知道 synchronized 关键字能实现线程安全,但是你知道这背后的原理是什么吗?今天我们就来讲一讲 synchronized 实现线程同步背后的原因,以及相关的锁优化策略吧. synchr ...
- Springboot 启动初始化bin,InitializingBean
import org.springframework.beans.factory.InitializingBean; @Componentpublic class TestInitializingBe ...
- (一)java基础篇-----认识java
1.简单介绍java起源: 1995年,詹姆斯-高斯林在sun公司开发出java编程语言.到2010年,sun公司被Oracle公司收购,而詹姆斯-高斯林也离开了Oracle公司.所以,如今想要安转j ...
- Ajax辨析
Ajax辨析 最近在多个知识点涉及到了ajax请求,各个知识有所交错,知识体系上学的有些混乱,这里梳理一下 单纯的发送Ajax请求 方式1: ajax传统4步骤 ajax的post请求 var xhr ...
- 算法竞赛进阶指南0x34矩阵乘法
文章目录 矩阵的相关性质再回顾 矩阵加速大法: ACWing205. 斐波那契 代码 ACWing206. 石头游戏 解题思路: 感受: 代码 矩阵的相关性质再回顾 对于一个矩阵 满足结合律 满足乘法 ...
- Netty-ProtobufVarint32
效果 ProtobufVarint32LengthFieldPrepender编码器用于在数据最前面添加Varint32,表示数据长度 ProtobufVarint32FrameDecoder是相对应 ...
- Gauss 消元法
目录 1. 线性方程组 2. 球形空间产生器sphere 3. 臭气弹 4. 开关问题 错乱瞎写 1. 线性方程组 省流:初等行变换化为一个上三角,然后瞬间出解 inline bool z(const ...
- 并发刺客(False Sharing)——并发程序的隐藏杀手
并发刺客(False Sharing)--并发程序的隐藏杀手 前言 前段时间在各种社交平台"雪糕刺客"这个词比较火,简单的来说就是雪糕的价格非常高!其实在并发程序当中也有一个刺客, ...