1.异步Promise
2.Module语法

1.异步Promise

Promise概述

JavaScript的执行环境是单线程。所谓单线程,是指JS引擎中负责解释和执行JavaScript代码的线程只有一个,也就是一次只能完成一项任务,这个任务执行完后才能执行下一个,它会「阻塞」其他任务。这个任务可称为主线程。

Promise的介绍和优点:
ES6中的Promise 是异步编程的一种方案。从语法上讲,Promise是一个对象,它可以获取异步操作的消息。Promise对象, 可以将异步操作以同步的流程表达出来。使用 Promise 主要有以下好处:

  • 可以很好地解决回调地狱的问题(避免了层层嵌套的回调函数)
  • 语法非常简洁,Promise 对象提供了简洁的API,使得控制异步操作更加容易

回调地狱的举例:
假设买菜、做饭、洗碗都是异步的。但真实的场景中,实际的操作流程是:买菜成功之后,才能开始做饭。做饭成功后,才能开始洗碗。这里面就涉及到了多层嵌套调用,也就是回调地狱

Promise基本用法

(1)使用new实例化一个Promise对象,Promise的构造函数中传递一个参数。这个参数是一个函数,该函数用于处理异步任务

(2)并且传入两个参数:resolve和reject,分别表示异步执行成功后的回调函数和异步执行失败后的回调函数

(3)通过promise.then()处理返回结果

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
// 带参数的异步请求简单案例
function queryData(params) {
return new Promise((resolve, reject) => {
setTimeout(function() {
let data = { retCode: 0, msg: 'success', data: params }; // 模拟接口返回的数据
if (data.retCode === 0) {
// 接口请求成功时调用
resolve(data);
} else {
// 接口请求失败时调用
reject({ retCode: -1, msg: 'network error', data: params });
}
}, 100);
});
}

queryData(params="赖萌蒙")
.then((data) => {
// 从 resolve 获取正常结果
console.log('接口请求成功时,走这里');
console.log(data);
})
.catch(function(data){
// 从 reject 获取异常结果
console.log('接口请求失败时,走这里');
console.log(data);
})
.finally(() => {
console.log('无论接口请求成功与否,都会走这里');
});

Promise对象状态

等待状态:pending
成功状态:fullfilled
失败状态:rejected

(1)当new Promise()执行之后,promise对象的状态会被初始化为pending,这个状态是初始化状态。new Promise()这行代码,括号里的内容是同步执行的。括号里定义一个function,function有两个参数:resolve和reject。如下:
如果请求成功了,则执行resolve(),此时,promise的状态会被自动修改为fullfilled。
如果请求失败了,则执行reject(),此时,promise的状态会被自动修改为rejected

(2)promise.then()方法,括号里面有两个参数,分别代表两个函数 function1 和 function2:
如果promise的状态为fullfilled(意思是:如果请求成功),则执行function1里的内容
如果promise的状态为rejected(意思是,如果请求失败),则执行function2里的内容
另外,resolve()和reject()这两个方法,是可以给promise.then()传递参数的

Promise的异步并发

Promise 自带的API提供了如下对象方法:

  • Promise.all():并发处理多个异步任务,所有任务都执行成功,才能得到结果(返回结果的顺序是 Promise.all(promiseArr) 里面promiseArr提供的顺序)
  • Promise.race(): 并发处理多个异步任务,只要有一个任务执行成功,就能得到结果
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 queryData(url) {
return new Promise((resolve, reject) => {
let data = { retCode: 0, msg: 'success', data: url }; // 模拟接口返回的数据
if (data.retCode === 0) {
// 接口请求成功时调用
resolve(data);
} else {
// 接口请求失败时调用
reject({ retCode: -1, msg: 'error', data: url });
}
});
}

Promise.all([queryData("google1.com"), queryData("google2.com"), queryData("google3.com")]).then((result) => {
console.log(result);
});

/*
返回的result结果:
[
{ retCode: 0, msg: 'success', data: 'https://www.baidu.com/' },
{ retCode: 0, msg: 'success', data: 'https://www.baidu.com/' },
{ retCode: 0, msg: 'success', data: 'https://www.baidu.com/' }
]
*/

2.Module语法

        历史上,JavaScript 一直没有模块(module)体系,无法将一个大程序拆分成互相依赖的小文件,再用简单的方法拼装起来。其他语言都有这项功能,比如 Ruby 的require、Python 的import,甚至就连 CSS 都有@import,但是 JavaScript 任何这方面的支持都没有,这对开发大型的、复杂的项目形成了巨大障碍。

        在 ES6 之前,社区制定了一些模块加载方案,最主要的有 CommonJS 和 AMD 两种。前者用于服务器,后者用于浏览器。ES6 在语言标准的层面上,实现了模块功能,而且实现得相当简单,完全可以取代 CommonJS 和 AMD 规范,成为浏览器和服务器通用的模块解决方案

CommonJS规范

ps:这里说明一下,下列所有的代码演示均为CommonJS规范(即Node.js规范),直接在浏览器上运行会报错

1.模块暴露

我们编写了一个hello.js文件,这个hello.js文件就是一个模块,模块的名字就是文件名(去掉.js后缀),所以hello.js文件就是名为hello的模块

1
2
3
4
5
6
7
8
9
'use strict';

let s = 'Hello';

function greet(name) {
console.log(s + ', ' + name + '!');
}

module.exports = greet;

module.exports把函数greet作为模块的输出暴露出去,这样其他模块就可以使用greet函数了

2.模块引入

1
2
3
4
5
6
7
8
'use strict';

// 引入hello模块:
let greet = require('./hello');

let s = 'Michael';

greet(s); // Hello, Michael!

3.多模块暴露

我们不妨深入♂一下:将某个模块暴露出来,并访问该模块内的多个函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// hello.static
'use strict';
let s = "hello python";
function conn(name){
console.log(s+','+name+'!');
return(s+","+name+"!")
}
function printer(n){
let ab = [];
if(n>=1){
for(let i = 0;i<n;i++){
ab.push(i)}
console.log(ab)
}else{
console.log("输入错误")
}
}
// 将模块暴露出来,以便于其它模块调用,采用对象的形式
module.exports ={conn:conn,printer:printer};

然后我们来访问hello模块,来玩♂一♀玩(注意模块里的函数调用方式)

1
2
3
4
5
6
// 主模块mian.static
'use strict';
let greet = require('./hello');
let s = "chd";
greet.conn(s);
greet.printer(10)

ES6规范

PS:在报错中了解到,是说无法在模块外部使用import语句,因为Module 的加载实现的是es6语法,所以在浏览器加载html文件时,需要在script 标签中加入type=”module”属性

更全的 ➡ Js模块化导入导出

参考文献


 评论

联系我 | Contact with me

Copyright © 2019-2020 谁知你知我,我知你知深。此恨经年深,比情度日久

博客内容遵循 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 协议