异步编程发展

异步编程经历了 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方法不传参数

  1. // 第一个promise
  2. const p = new Promise(resolve => {
  3. throw new Error('test'); // 抛出错误
  4. });
  5. // 第二个promise
  6. p.then(
  7. () => {} // 这里是状态变为fullfilled的回调函数
  8. // 这里空着的,本应该填的是状态变为rejected的回调函数,所以不传递参数
  9. )
  10. // 第三个promise
  11. .then(
  12. data => console.log('resolve', data),
  13. err => console.log('reject', err)
  14. )
  15. // 运行结果:reject Error: test
  16. // 可见,第一个promise抛出的错误,即使第二个promise没有rejected回调函数,第三个promise的rejected回调函数依旧能接受到参数
  17. // 结论:无论onFullfilled还是onRjected中,上一个promise不对参数进行处理,下一个promise进行处理

then方法回调不返回值

  1. // 第一个promise
  2. const p = new Promise(resolve => {
  3. resolve('test')
  4. });
  5. // 第二个promise
  6. p.then(() => {
  7. () => {} // 状态变成fullfilled的回调函数,没有返回值
  8. })
  9. // 第三个promise
  10. .then(
  11. data => console.log('resolve', data),
  12. err => console.log('reject', err)
  13. )
  14. // 运行结果:resolve undefined
  1. // 第一个promise
  2. const p = new Promise(() => {
  3. throw new Error('error');
  4. });
  5. // 第二个promise
  6. p.then(
  7. () => {},
  8. () => {} // 状态变成rejected的回调函数,没有返回值
  9. )
  10. // 第三个promise
  11. .then(
  12. data => console.log('resolve', data),
  13. err => console.log('reject', err)
  14. )
  15. // 运行结果:resolve undefined
  16. // 结论:无论onFullfilled还是onRjected中,then方法回调不返回值,状态都会变成fullfilled,走fullfilled的回调函数

then方法回调返回普通值

  1. var p = new Promise(resolve => {
  2. throw new Error('test');
  3. });
  4. p.then(
  5. () => { return 'a' },
  6. () => { return {b: 1} }
  7. ).then(
  8. (data) => console.log("resolve", data),
  9. (err) => console.log("reject", err)
  10. );
  11. // 运行结果:resolve {b: 1}
  12. // 结论:无论onFullfilled还是onRjected中,then方法回调返回普通值,状态都会变成fullfilled,走fullfilled的回调函数

then方法回调返回promise

  1. var p = new Promise(resolve => {
  2. throw new Error('test');
  3. });
  4. p.then(
  5. () => { return 'a' },
  6. () => { return Promise.resolve('test') }
  7. ).then(
  8. (data) => console.log("resolve", data),
  9. (err) => console.log("reject", err)
  10. );
  11. // 运行结果:resolve test
  12. // 结论:无论onFullfilled还是onRjected中,返回一个promise对象,则以该promise的任务和状态返回新的promise

then方法回调返回thenable对象

  1. var p = new Promise((r) => {throw new Error('test')});
  2. p.then(
  3. () => ({then: function(resolvePromise, rejectPromise) {resolvePromise('resolvePromise')}}),
  4. e => ({then: function(resolvePromise, rejectPromise) {rejectPromise('rejectPromise')}})
  5. )
  6. .then(
  7. data => console.log('resolve', data),
  8. e => console.log('reject', e)
  9. );
  10. // 运行结果:reject rejectPromise
  11. // 结论:无论onFullfilled中还是onRejected中,返回一个thenable对象,则调用该对象的then方法,该then方法接收两个参数resolvePromise和rejectPromise。
  12. // 如果then中调用了resolvePromise,则返回的promise状态置为fullfilled,如果then中调用了rejectPromise,或者then中抛出异常,则返回的Promise状态置为rejected。
  13. // 在调用resolvePromise或者rejectPromise之前,返回的promise处于pending状态。

then方法回调抛出错误

无论onFullfilled中还是onRejected中,抛出错误,则以rejected为状态返回新promise。

catch

catch方法和then方法的reject回调用法相同,如果这时候任务处于rejected状态,则直接执行catch,catch的参数就是reject的reason;

  1. var p = new Promise(resolve => {
  2. throw new Error('test');
  3. });
  4. // catch写法
  5. p.catch((err) => {
  6. console.log(err);
  7. })
  8. // 两种写法等价
  9. p.then(
  10. undefined,
  11. (err) => {
  12. console.log(err);
  13. }
  14. )

all

Promise.all方法接收一个promise数组作为参数,返回一个promise,当参数的数组中的所有promise都resolve时候,返回的promise才会resolve;而若有一个参数的数组中的promise reject,返回的promise就会reject。

  1. var p1 = Promise.resolve(1);
  2. var p2 = new Promise(resolve => {
  3. setTimeout(() => {
  4. resolve(2);
  5. }, 1000);
  6. })
  7. Promise.all([p1, p2])
  8. .then(
  9. ([result1, result2]) => {console.log('resolve', result1, result2);}
  10. )
  11. // 运行结果:resolve 1 2

race

Promise.race接收一个promise数组作为参数,返回一个新的promise。当参数数组中其中一个promise resolve或者reject,返回的promise就相应地改变状态。

  1. var p1 = Promise.reject(1);
  2. var p2 = new Promise(resolve => {
  3. setTimeout(() => {
  4. resolve(2);
  5. }, 1000);
  6. });
  7. Promise.race([p1, p2])
  8. .then(
  9. data => {console.log('resolve', data);},
  10. e => {console.log('reject', e);}
  11. );
  12. // 运行结果:reject 1

allSettled

Promise.allSettled用于多个异步任务都结束(完成或者失败)时候,再执行后续任务的场景。

Promise.allSettled接收一个promise数组作为参数,返回一个promise。当参数数组中所有promise状态改变后,返回的promise变为fullfilled状态。

返回的promise的onFullfilled参数接收一个结果数组作为参数,数组对应Promise.allSettled传入的promise数组。结果数组每个元素是一个对象,格式固定:{status, value, reason},标识状态、resolve返回值、reject原因。

  1. var p1 = Promise.reject(1);
  2. var p2 = new Promise(resolve => {
  3. setTimeout(() => {
  4. resolve(2);
  5. }, 1000);
  6. });
  7. Promise.allSettled([p1, p2])
  8. .then(
  9. data => {console.log('resolve', data);},
  10. );
  11. // 运行结果:resolve [{status: "rejected", reason: 1}, {status: "fulfilled", value: 2}]

异步编程promise的更多相关文章

  1. 简单实现异步编程promise模式

    本篇文章主要介绍了异步编程promise模式的简单实现,并对每一步进行了分析,需要的朋友可以参考下 异步编程 javascript异步编程, web2.0时代比较热门的编程方式,我们平时码的时候也或多 ...

  2. 异步编程——promise

    异步编程--promise 定义 Promise是异步编程的一个解决方案,相比传统的解决方法--回调函数,使用Promise更为合理和强大,避免了回调函数之间的层层嵌套,也使得代码结构更为清晰,便于维 ...

  3. 异步编程Promise/Deferred、多线程WebWorker

    长期以来JS都是以单线程的模式运行的,而JS又通常应用在操作用户界面和网络请求这些任务上.操作用户界面时不能进行耗时较长的操作否则会导致界面卡死,而网络请求和动画等就是耗时较长的操作.所以在JS中经常 ...

  4. 简述异步编程&Promise&异步函数

    前言:文章由本人在学习之余总结巩固思路,不足之前还请指出. 一.异步编程 首先我们先简单来回顾一下同步API和异步API的概念 1.同步API:只有当前的API执行完成之前,才会执行下一个API 例: ...

  5. AnjularJS异步编程 Promise和$q

    Promise,是一种异步处理模式. js代码的函数嵌套会使得程序执行异步代码时很难调试.因为多重嵌套的函数无法确定何时触发回调. 如: funA(arg1,arg2,function(){ func ...

  6. es6异步编程 Promise 讲解 --------各个优点缺点总结

    //引入模块 let fs=require('fs'); //异步读文件方法,但是同步执行 function read(url) { //new Promise 需要传入一个executor 执行器 ...

  7. 你所必须掌握的三种异步编程方法callbacks,listeners,promise

    目录: 前言 Callbacks Listeners Promise 前言 coder都知道,javascript语言运行环境是单线程的,这意味着任何两行代码都不能同时运行.多任务同时进行时,实质上形 ...

  8. JavaScript异步编程 ( 一 )

    1. 异步编程 Javascript语言的执行环境是"单线程"(single thread).所谓"单线程",就是指一次只能完成一件任务.如果有多个任务,就必须 ...

  9. JavaScript异步编程(1)- ECMAScript 6的Promise对象

    JavaScript的Callback机制深入人心.而ECMAScript的世界同样充斥的各种异步操作(异步IO.setTimeout等).异步和Callback的搭载很容易就衍生"回调金字 ...

随机推荐

  1. centos7解决无法上网的问题

    问题:centos7出现无法进行联网,如下图所示,执行该命令: ping qq.com 出现如下情况: 解决方法: 首先cd到需要修改文件的所在目录下: [root@localhost ~]# cd ...

  2. 写了个 Markdown 命令行小工具,希望能提高园友们发文的效率!

    写了个 Markdown 命令行小工具,希望能提高园友们发文的效率! 前言 笔者使用 Typora 来编写 Markdown 格式的博文,图片采用的是本地相对路径存储(太懒了不想折腾图床). 时间久了 ...

  3. Java 浅做计算器

    package www.nihao; import java.util.Scanner; public class counter { public static void main(String[] ...

  4. day05 Java网络编程socket 与多线程

    java网络编程 java.net.Socket Socket(套接字)封装了TCP协议的通讯细节,是的我们使用它可以与服务端建立网络链接,并通过 它获取两个流(一个输入一个输出),然后使用这两个流的 ...

  5. 机器学习-Kmeans

    一.什么是聚类算法? 1.用于发现共同的群体(cluster),比如:邮件聚类.用户聚类.图片边缘. 2.聚类唯一会使用到的信息是:样本与样本之间的相似度(跟距离负相关) 给定N个训练样本(未标记的) ...

  6. 痞子衡嵌入式:MCUXpresso IDE下将源码制作成Lib库方法及其与IAR,MDK差异

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是MCUXpresso IDE下将源码制作成Lib库方法及其与IAR,MDK差异. 程序函数库是一个包含已经编译好代码和数据的函数集合,这 ...

  7. C#Lambda表达式演变和Linq的深度解析

    Lambda 一.Lambda的演变 Lambda的演变,从下面的类中可以看出,.Net Framwork1.0时还是用方法实例化委托的,2.0的时候出现了匿名方法,3.0的时候出现了Lambda. ...

  8. Collection集合和Collection的常用功能

    boolean add(E e); 向集合里添加元素 boolean remove(E e); 删除集合中的某个元素 void clear(); 清空集合的所有元素 boolean contains( ...

  9. LeetCode题解-20.有效的括号

    题目 给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效. 有效字符串需满足: 左括号必须用相同类型的右括号闭合. 左括号必须以正确的顺序闭合. 示例 ...

  10. Python 懂车帝口碑分爬虫

    本文所有教程及源码.软件仅为技术研究.不涉及计算机信息系统功能的删除.修改.增加.干扰,更不会影响计算机信息系统的正常运行.不得将代码用于非法用途,如侵立删! Python 懂车帝口碑分爬虫 需求 懂 ...