前端的异步解决方案之Promise和Await-Async

前端异步操作大杂烩(ajax、fetch、promise、async/await) 写在前面的话一、为什么需要异步操作?二、服务器交互的异步(Ajax---->Promise---->Fetch)2.1 Ajax:2.2 Promise2.3 Fetch2.4 async/await三、实战利器参考链接 前端工作中面临两个重要的问题:同步与异步操作。   同步操作,用户操作即时显示的,比如切换菜单,按钮点击效果等等。   异步操... 阅读详情
异步编程模式在 前端开发 过程中,显得越来越重要。从最开始的XHR到封装后的Ajax都在试图解决异步编程过程中的问题。随着ES6新标准的出来,处理异步数据流的解决方案又有了新的变化。 Promise 就是这其中的一个。我们都知道,在传统的ajax请求中,当异步请求之间的数据存在依赖关系的时候,就可能产生很难看的多层回调,俗称”回调地狱”(callback hell)。另一方面,往往错误处理的代码和正常的业务代码耦合在一起,造成代码会极其难看。为了让编程更美好,我们就需要引入 promise 来降低异步编程的复杂性。

Promise

Promise 对象是一个返回值的代理,这个返回值在promise对象创建时未必已知。它允许你为异步操作的成功返回值或失败信息指定处理方法。 这使得异步方法可以像同步方法那样返回值:异步方法会返回一个包含了原返回值的 promise 对象来替代原返回值。 ——MDN

我们来看一下官方定义,Promise实际上就是一个特殊的JavaScript对象,反映了”异步操作的最终值”。”Promise”直译过来有预期的意思,因此,它也代表了某种承诺,即无论你异步操作成功与否,这个对象最终都会返回一个值给你。
先写一个简单的demo来直观感受一下:

      
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
      
const promise = new Promise( (resolve, reject) => {
$.ajax( 'https://github.com/users', (value) => {
resolve(value);
}).fail( (err) => {
reject(err);
});
});
promise.then( (value) => {
console.log(value);
},(err) => {
console.log(err);
});
//也可以采取下面这种写法
promise.then( value => console.log(value)).catch( err => console.log(err));

上面的例子,会在Ajax请求成功后调用resolve回调函数来处理结果,如果请求失败则调用reject回调函数来处理错误。Promise对象内部包含三种状态,分别为pending,fulfilled和rejected。这三种状态可以类比于我们平常在ajax数据请求过程的pending,success,error。一开始请求发出后,状态是Pending,表示正在等待处理完毕,这个状态是中间状态而且是单向不可逆的。成功获得值后状态就变为fulfilled,然后将成功获取到的值存储起来,后续可以通过调用then方法传入的回调函数来进一步处理。而如果失败了的话,状态变为rejected,错误可以选择抛出(throw)或者调用reject方法来处理。

请求的几个状态:

  1. pending( 中间状态)—> fulfilled , rejected
  2. fulfilled(最终态)—> 返回value 不可变
  3. rejected(最终态) —> 返回reason 不可变

如图所示:

promisespromises

promise

一个promise内部可以返回另一个promise,这样就可以进行层级调用。

      
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
      
const getAllUsers = new Promise( (resolve, reject) => {
$.ajax( 'https://github.com/users', (value) => {
resolve(value);
}).fail( (err) => {
reject(err);
});
});
const getUserProfile = function(username) {
return new Promise( (resolve, reject) => {
$.ajax( 'https://github.com/users' + username, (value) => {
resolve(value);
}).fail( (err) => {
reject(err);
});
};
getAllUsers.then( (users) => {
//获取第一个用户的信息
return getUserProfile(users[ 0]);
}).then( (profile) => {
console.log(profile)
}).catch( err => console.log(err));

Promise实现原理

目前,有多种Promise的实现方式,我选择了https://github.com/then/promise的源码进行阅读。

      
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
      
function Promise(fn) {
var state = null; //用以保存处理状态,true为fulfilled状态,false为rejected状态
var value = null; //用以保存处理结果值
var deferreds = [];
var self = this;
this.then = function(onFulfilled, onRejected) {
return new self.constructor(
function(resolve, reject) {...}
);
}; //返回一个延迟处理函数,调用这个方法,就能触发用户传入的处理函数,分别对应处理promise的fulfilled状态和rejected状态
function handle(deferred) {...} //延迟队列处理
function resolve(newValue) {...} //更新value值,并把state更新为true,代表结果正常
function reject(newValue) {...} //更新vlaue值,并把state更新为false,代表结果错误,这个value值就是错误原因方便后面调用处理
function finale() {...} //清空异步队列
doResolve(fn, resolve, reject); //调用resolve和reject两个回调函数处理结果
}

通过阅读promise的源码,我们可以很清楚地看到,在构建一个promise对象的时候,是利用函数式编程的特性,如惰性求值和部分求值等来进行将异步处理的。而处理多线程并发的机制就是利用setTimeout(fn,0)这个技巧。

构造Promise

Promise构造函数的初始函数需要有两个参数,resolve和reject,分别对应fulfilled和rejected两个状态的处理。

      
1
2
3
4
5
6
7
8
      
var promise = new Promise( (resolve, reject) => {
try {
var value = doSomething();
resolve(value);
} catch(err) {
reject(err);
}
});

Promise的常用方法

1.Promise.all(iterator):

​ 返回一个新的promise对象,其中所有promise的对象成功触发的时候,该对象才会触发成功,若有任何一个发成错误,就会触发改对象的失败方法。成功触发的返回值是所有promise对象返回值组成的数组。直接看例子吧:

      
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
      
//设置三个任务
const tasks = {
task1() {
return new Promise(...); //return 1
},
task2() {
return new Promise(...); // return 2
},
task3() {
return new Promise(...); // return 3
}
};
//列表中的所有任务会并发执行,当所有任务执行状态都为fulfilled后,执行then方法
Promise.all([tasks.task1(), tasks.task2(), tasks.task3()]).then( result => console.log(result));
//最终结果为:[1,2,3]

2.Promise.race(iterable): 返回一个新的promise对象,其回调函数迭代遍历每个值,分别处理。同样都是传入一组promise对象进行处理,同Promise.all不同的是,只要其中有一个promise的状态变为fulfilled或rejected,就会调用后续的操作。

      
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
      
//设置三个任务
const tasks = {
task1() {
return new Promise(...); //return 1
},
task2() {
return new Promise(...); // return 2
},
task3() {
return new Promise(...); // return 3
}
};
//列表中的所有任务会并发执行,只要有一个promise对象出现结果,就会执行then方法
Promise.race([tasks.task1(), tasks.task2(), tasks.task3()]).then( result => console.log(result));
//假设任务1最开始返回结果,则控制台打印结果为`1`

3.Promise.reject(reason): 返回一个新的promise对象,用reason值直接将状态变为rejected。

      
1
2
3
4
5
      
const promise2 = new Promise( (resolve, reject) => {
reject( 'Failed');
});
const promise2 = Promise.reject( 'Failed');

上面两种写法是等价的。

4.Promise.resolve(value): 返回一个新的promise对象,这个promise对象是被resolved的。

与reject类似,下面这两种写法也是等价的。

      
1
2
3
4
5
      
const promise2 = new Promise( (resolve, reject) => {
resolve( 'Success');
});
const promise2 = Promise.resolve( 'Success');

5.then 利用这个方法访问值或者错误原因。其回调函数就是用来处理异步处理返回值的。

6.catch 利用这个方法捕获错误,并处理。

Generator & Iterator 迭代器和生成器

虽然Promise解决了回调地狱(callback hell)的问题,但是仍然需要在使用的时候考虑到非同步的情况,而有没有什么办法能让异步处理的代码写起来更简单呢?在介绍解决方案之前,我们先来介绍一下ES6中有的迭代器和生成器。
迭代器(Iterator),顾名思义,它的作用就是用来迭代遍历集合对象。
在ES6语法中迭代器是一个有next方法的对象,可以利用Symbol.iterator的标志返回一个迭代器。

      
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
      
const getNum = {
[ Symbol.iterator]() {
let arr = [ 1, 2, 3];
let i = 0;
return {
next() {
return i < arr.length ? { value: arr[i++]} : { done: true};
}
}
}
}
//利用for...of语法遍历迭代器
for( const num of getNum) {
console.log(num);
}

而生成器(Generator)可以看做一个特殊的迭代器,你可以不用纠结迭代器的定义形式,使用更加友好地方式实现代码逻辑。
先来看一段简单的代码:

      
1
2
3
4
5
6
7
8
9
10
11
      
function* getNum() {
yield 1;
yield 2;
yield 3;
}
//调用生成器,生成一个可迭代的对象
const gen = getNum();
gen.next(); // {value: 1, done: false}
gen.next(); // {value: 2, done: false}
gen.next(); // {value: 3, done: true}

生成器函数的定义需要使用function*的形式,这也是它和普通函数定义的区别。yield是一个类似return的关键字,当代码执行到这里的时候,会暂停当前函数的执行,并保存当前的堆栈信息,返回yield后面跟着表达式的值,这个值就是上面代码所看到的value所对应的值。而done这个属性表示是否还有更多的元素。当done为true的时候,就表明这个迭代过程结束了。需要注意的是这个next方法其实传入参数,这个参数表示上一个yield语句的返回值,如果你给next方法传入了参数,就会将上一次yield语句的值设置为对应值。

利用generator的异步处理

先来看一下下面这段代码:

      
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
      
function getFirstName() {
setTimeout( () => {
gen.next( 'hello');
}, 2000);
}
function getLastName() {
setTimeout( () => {
gen.next( 'world');
}, 1000);
}
function* say() {
let firstName = yield getFirstName();
let lastName = yield getLastName();
console.log(firstName + lastName);
}
var gen = say();
gen.next(); // {value: undefined, done: false}
//helloworld

我们可以发现,当第一次调用gen.next()后,程序执行到第一个yield语句就中断了,而在getFirstName里显式地将上一个yield语句的返回值改为hello,触发了第二yield语句的执行。以此类推,最终就打印出我们想要的结果了。

spawn函数

我们可以考虑把上面的代码改写一下,在这里将Promise和Generator结合起来,将异步操作用Promise对象封装好,然后,resolve出去,而创建一个spawn函数,这个函数的作用是自动触发generator的next方法。来看一下代码:

      
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
      
function getFirstName() {
return new Promise( (resolve, reject) => {
setTimeout( () => {
resolve( 'hello');
}, 2000);
});
}
function getLastName() {
return new Promise( (resolve, reject) => {
setTimeout( () => {
resolve( 'world');
}, 1000);
});
}
function* say() {
let firstName = yield getFirstName();
let lastName = yield getLastName();
console.log(firstName + lastName);
}
function spawn(generator) {
return new Promise( (resolve, reject) => {
var onResult = (lastPromiseResult) => {
var {value, done} = generator.next(lastPromiseResult);
if(!done) {
value.then(onResult, reject);
} else {
resolve(value);
}
}
onResult();
});
}
spawn(say()).then( (value) => { console.log(value)});

到这里,这个解决方案就很接近接下来要介绍的async/await的实现方式了。

Async/Await

这两个关键字其实是一起使用的,async函数其实就相当于funciton *的作用,而await就相当与yield的作用。而在async/await机制中,自动包含了我们上述封装出来的spawn自动执行函数。
利用这两个新的关键字,可以让代码更加简洁和明了:

      
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
      
function getFirstName() {
return new Promise( (resolve, reject) => {
setTimeout( () => {
console.log( 'hello');
resolve( 'hello');
}, 2000);
});
}
function getLastName() {
return new Promise( (resolve, reject) => {
setTimeout( () => {
console.log( 'world');
resolve( 'world');
}, 1000);
});
}
async function say() {
let firstName = await getFirstName();
let secondName = await getLastName();
return firstName + lastName;
}
console.log(say());

执行结果为,先等待2秒打印hello,再等待1秒打印world,最后打印’helloworld’,与预期的执行顺序是一致的。

上面的代码你需要注意的是,你必须显式声明await,否则你会得到一个promise对象而不是你想要获得的值。

比起Generator函数,async/await的语义更好,代码写起来更加自然。将异步处理的逻辑放在语法层面去处理,写的代码也更加符合人的自然思考方式。

错误处理

对于async/await这种方法来说,错误处理也比较符合我们平常编写同步代码时候处理的逻辑,直接使用try..catch就可以了。

      
1
2
3
4
5
6
7
8
9
10
11
12
13
14
      
function getUsers() {
return $.ajax( 'https://github.com/users');
}
async function getFirstUser() {
try {
let users = await getUsers();
return users[ 0].name;
} catch (err) {
return {
name: 'default user'
}
}
}

写在最后

目前,Service Workers、 Fetch、 Streams、Loader 等全部基于 Promise。可以预见,在未来的javascript异步编程中,Promise及其衍生出来的技术必将大放异彩。那么,你准备好了吗?

原文地址:

http://scq000.github.io/2016/11/05/%E5%89%8D%E7%AB%AF%E7%9A%84%E5%BC%82%E6%AD%A5%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88%E4%B9%8BPromise%E5%92%8CAwait-Async/

Es6 Promise,Es7 async await实战教程 一个案例让你吃透Es6的promise和Es7的async await 阅读详情

相关推荐

JavaScript 异步方案 async/await

从代码片段中不难看出 Promise 没有解决好的事情,比如要有很多的 then 方法,整块代码会充满 Promise 的方法,而不是业务逻辑本身,而且每一个 then 方法内部是一个独立的作用域,要是想共享数据,就要将部分数据暴露在最外层,在 then 内部赋值一次。可以看出 RxJS 对于这类数据可以做一种类似流式的处理,也是非常优雅,而且 RxJS 强大之处在于你还可以对数据做取消、监听、节流等等的操作,这里不一一举例了,感兴趣的话可以去看下 RxJS 的 API。恶梦和无数的 then 方法。

xiaoweids的博客 318

async/await实现Promise.all()

Promise.all() 方法接收一个 promise 的 iterable 类型(注:Array,Map,Set 都属于 ES6 的 iterable 类型)的输入,并且只返回一个Promise实例,并且输入的所有 promise 的 resolve 回调的结果是一个数组。Promise的 resolve 回调执行是在所有输入的 promise 的 resolve 回调都结束,或者输入的 iterable 里没有 promise 了的时候。

编码世界 5184

JS-Promise的缺点和解决方案

前端校招精编面试解析大全点击这里获取完整版pdf查看有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!**[外链图片转存中…(img-fuHo1IcB-1712941943959)]由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:前端)前端校招精编面试解析大全点击这里获取完整版pdf查看。

2301_77110865的博客 470

SpringBoot异步任务, 以及带返回值的异步任务(@Async 不起作用的原因

SpringBoot异步任务, 以及带返回值的异步任务(@Async 不起作用的原因) 第一部分: 无返回值异步任务 当没有加入异步任务的时候,我们创建一个service ,里面的方法需要等待3秒才能完成, controller层写一个测试方法调用时间返回的接口, 直接调用, 下面是service层代码部分 package com.zz.amqp1.service; import org.springframework.stereotype.Service; import java.util.Dat

挑灯看繁华的博客 1411

前端开发:解决异步回调必备技能——Async/Await和Promise丨蓄力计划

做过前端开发的开发者应该都知道JavaScript是单线程语言,浏览器只分配给JS一个主线程,用来执行任务,但是每次一次只能执行一个任务,这些任务形成一个任务队列排队等候执行;但是某些任务是比较耗时的,如网络请求,事件的监听,以及定时器,如果让这些非常耗时的任务一一排队等候执行,那么程序执行效率会非常的低,甚至会导致页面假死。因此,浏览器为这些耗时的任务开辟了新的线程,主要包括http请求线程、浏览器事件触发线程、浏览器定时触发器,但是这些任务都是异步的,这就涉及到了前端开发的异步回调操作处理。 ...

全沾软贱开发攻城狮 1万+

PLC作为Modbus TCP客户端

PLC作为Modbus TCP客户端,Modbus Slave作为服务器

soledad_chao的博客 4378

springboot---@Async实现异步调用及异步回调Future

异步调用相对的是同步调用。 同步方法调用的时候必须是按照顺序执行的,上一行代码执行完,才会执行下一行。而异步方法调用是相当于多个线程执行,不需要等待上一行代码的执行结果。 首先测试方法同步的情况: controller: package springboot_async.async_test; import org.springframework.beans.factory.annot...

QYHuiiQ 3万+

AI辅助专利撰写实战:用Codex 30分钟生成发明专利初稿

这次我们来看一个用 Codex 从零开始撰写发明专利的实战项目。对于技术研发人员、产品经理或初创团队来说,专利申请是保护创新成果、构建技术壁垒的关键一步。然而,撰写一份高质量的专利申请书,尤其是权利要求书和说明书,往往需要专业的法律和技术语言,耗时耗力。这个项目演示了如何利用 AI 工具 Codex,在短时间内生成一份结构完整、逻辑清晰、具备授权潜力的专利申请文件初稿。 整个过程的核心不是让 AI 完全替代专利代理人,而是将其作为强大的“技术翻译”和“内容生成”助手。它能将你的技术构思、流程图、核心算法或产

weixin_32181267的博客 414

Spring Boot使用@Async实现异步调用:使用Future以及定义超时

之前连续写了几篇关于使用 @Async实现异步调用的内容,也得到不少童鞋的反馈,其中问题比较多的就是关于返回 Future的使用方法以及对异步执行的超时控制,所以这篇就来...

程序猿DD 6708

Elasticsearch连接中断:深入解析Connection reset by peer问题及优化策略

本文深入解析Elasticsearch连接中断问题,特别是Connection reset by peer错误的成因与解决方案。从TCP层的心跳机制到客户端与服务端的配置差异,详细介绍了网络不稳定、防火墙拦截等常见原因,并提供了六种优化策略,包括KeepAlive调整、TCP参数调优和智能重试机制等,帮助提升Elasticsearch连接的稳定性。

weixin_42546392的博客 410

SAP SD核心流程解析:从销售订单到财务结算的实战指南

本文深入解析SAP SD模块从销售订单到财务结算的核心流程,重点剖析了销售订单中的行项目类别如何作为流程的“总开关”,决定了后续交货、开票及财务集成的走向。文章结合实战案例,详细拆解了正常销售、退货、第三方销售、寄售等典型流程的配置要点与国内化适配方案,并阐述了SD与财务模块集成的关键连接点,为顾问和用户提供了一份全面的实战指南。

weixin_29250403的博客 426

前端的异步解决方案之Promise和Await/Async

前端的异步解决方案之Promise和Await/Async

qq_38472465的博客 177

新手入门:N-CMAPSS数据集解析与实战指南

本文详细解析了N-CMAPSS数据集的结构与应用,为新手提供航空发动机故障预测的实战指南。通过Python代码示例展示数据加载、探索和特征工程技巧,帮助读者快速掌握剩余寿命(RUL)预测的关键步骤,并分享常见问题解决方案与进阶学习路径。

weixin_29056701的博客 376

前端常见浏览器兼容性问题解决方案和前端异步(async,await)解决方案(所有方案)Promise

https://blog.youkuaiyun.com/weixin_43638968/article/details/109177674 https://blog.youkuaiyun.com/qq_32442973/article/details/89322763

liulang68的博客 2158

观测器选择与工程实践建议

摘要:永磁同步电机(PMSM)无传感器控制中,观测器选型需综合考虑应用场景、性能需求与成本。消费级(家电、工具)推荐滑模观测器(SMO),成本低、鲁棒性强;工业级(伺服、泵阀)适用扩展卡尔曼滤波器(EKF),精度高但计算复杂;车规级(EPS、主驱动)需混合观测器(SMO+EKF),兼顾全速域性能与可靠性。低速时需高频注入法,IPMSM更适用。SMO易实现但存在抖振,EKF调试复杂。未来趋势是混合架构与AI增强,提升适应性与性能。选型需权衡速度范围、电机类型、处理器能力及成本。

汽车软件开发 146

AI驱动芯片设计的端到端验证:AI应用架构师的全流程指南

想象你要建造一座1000层的超级摩天大楼,每个房间都有独特的功能,管道、电路、电梯系统交织如迷宫。传统的检查方式是派1000个工程师逐层逐房手动检查,耗时十年且仍可能遗漏火灾隐患。这就是今天芯片设计面临的困境:7nm芯片含百亿晶体管,相当于百亿个"房间",传统验证方法(人工编写测试用例、随机仿真)已难以应对。本文的目的,是为AI应用架构师提供一份"AI驱动芯片验证导航图",范围涵盖从验证需求分析到芯片签核的全流程,包括AI模型如何融入传统验证工具链、数据如何驱动验证效率提升、以及端到端闭环系统的构建方法。

2501_92132293的博客 1241

javascript之异步操作理解---回调函数,async,await以及promise对象

javascript之异步操作理解---回调函数,async,await以及promise对象概述 概述 写在前面:虽然平时做项目,但是发现自己写的代码还是很烂。最近接触了一个对性能要求比较高的项目,于是重新开始审视自己写的代码是不是达到尽量较小系统性能了。加上前几天学到express框架了解到了回调函数的操作。作为拓展,查了许多资料,再次总结一下javascript的异步操作。 javascript是一门单线程语言,即一次只能完成一个任务,若有多个任务要执行,则必须排队按照队列来执行(前一个任务完成,

qq_44774831的博客 4384

把数据库算力拉满的 ABAP CDS Table Function:从语法、权限到可运行样例的全景解析

文章摘要: 本文针对ABAP开发者探讨了CDS Table Function的应用场景与实现细节。当CDS View无法处理复杂计算(如窗口函数、递归等)时,可通过Table Function将逻辑下推到HANA数据库执行。关键点包括:1)CDS实体声明与AMDP实现的协作关系;2)多租户环境下的Client处理机制(@ClientHandling.type注解);3)激活与传输的阶段性特点可能导致的"暂不可用"问题;4)基于SFLIGHT的完整示例,展示如何定义Client依赖函数、实

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 306

关于JavaScript 异步方案 async/await

转自:微点阅读https://www.weidianyuedu.com 目前最好的 JavaScript 异步方案async/await 构建一个应用程序总是会面对异步调用,不论是在 Web 前端界面,还是 Node.js 服务端都是如此,JavaScript 里面处理异步调用一直是非常恶心的一件事情。以前只能通过回调函数,后来渐渐又演化出来很多方案,最后 Promise 以简单、易用、兼容性好取胜,但是仍然有非常多的问题。其实 JavaScript 一直想在语言层面彻底解决这个问题,在 E..

ysds20211402的博客 339

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

前端面试,讲一下 promise,async,await,如何快速理解和记忆

**错误处理** | 需手动链式调用 `.catch` | 直接用 `try/catch` 捕获 |> 2. **错误处理**:Promise 需手动 `.catch`,async/await 直接用 `try/catch`。> - **下单中(pending)** → **送达(fulfilled)** 或 **取消(rejected)**> - **.then(吃外卖)** → **.catch(投诉)** → **.finally(收拾包装)**”

m0_55866389的博客 363

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

前端实现异步的方法

实现异步的方法

Senora的博客 3640

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

异步解决方案----Promise与Await

异步解决方案----Promise与Await 前言 异步编程模式在前端开发过程中,显得越来越重要。从最开始的XHR到封装后的Ajax都在试图解决异步编程过程中的问题。随着ES6新标准的到来,处理异步数据流又有了新的方案。我们都知道,在传统的ajax请求中,当异步请求之间的数据存在依赖关系的时候,就可能产生很难看的多层回调,俗称'回调地狱'(cal...

w1366352655的博客 290

前端返回为Promise的情况解决

前端p返回 promise 问题解决

qq_24970227的博客 1743
上一篇: html-webpack-plugin用法全解
下一篇: Angularjs中的$Http与$resource
SunsCheung
博客等级 码龄11年 30粉丝 27原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值