博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
javascript 总结笔记
阅读量:6986 次
发布时间:2019-06-27

本文共 18171 字,大约阅读时间需要 60 分钟。

时间匆匆, 转眼毕业已经快两年了。 最为一个前端小白的我, 现在怎么说也是灰色的了吧? 前段时间一直有个想法: 想把自己学到的前端知识点整理下,感觉这样有助于自己基础的巩固。 所以才有个今天这个js知识点回顾文章。 好吧,废话少说了, 先从javascript开席吧!

前言:

毕业的时候本来不是做前端的。 作为一个后台培训出来的应届生。 匆匆培训java、html、 css、 java2ee 、ssh等一大堆东西。第一家公司是来上海做后台。 记得有一次项目中老大说让我整理个页面, 当时懵逼了都。 什么? 让我写个ajax ? !虽然培训过前端方面的知识, 但是也只是匆匆而过,有个大概的了解。 没办法只能硬着头皮上网上找资料啊。 心想如果做不出来,会不会被开除啊?( 我想每个实习期的童鞋都有这样的经历吧 哈哈...)这就算是我第一次真正接触前端。 嗯 ,没毛病。

正文:

1、 JavaScript简介

JavaScript 和java 没个卵的关系。 ECMAScript就是对实现该标准规定的各个方面内容的语言的描述。

JavaScript实现了ECMAScript。 所以什么es5 es6 es7 是ECMAScript5 6 7 的简写。 至于其它概念,大概看下就行。(只是本人自己的看法)!

JavaScript在当前五个主要浏览器( IE、 Firefox、 Chrome、 Safari和 Opera) 中 都得到了不同程度的支持。 所以才有了兼容性的问题。 但人类的脚步是向前的。 比如babel 编译器解决了这种差异。统一编译成es5。呵呵哒!

2、 推荐在javaScript 中使用 "use strict" 。why ? 让我就举个栗子:

"use strict"; //在正常模式中,如果一个变量没有声明就赋值,默认是全局变量。严格模式禁止这种用法,全局变量必须显式声明。v = 1; // 报错,v未声明for (i = 0; i < 2; i++) { // 报错,i未声明}//因此, 严格模式下, 变量都必须先用var命令声明, 然后再使用。function f() { return this; //非严格模式下 因为"this"指向全局对象,返回全局对象}function f() { "use strict"; //这行代码看起来像是字符串,而且也没有赋值给任何变量,但其实它是一个编译指示(pragma),// 用于告诉支持的 JavaScript引擎切换到严格模式return this; //严格模式下 this的值为undefined,}复制代码

严格模式下方法入参不能有重复定义的变量、 对象不能有重复的属性。。。

而且有时候  "use strict"可以节省函数执行的时间。

推荐语句以一个分号结尾。(以前做的一个vuejs项目 eslint 不能用; 结尾 结果我们公司有个大大牛就问了 你们js为什么语句不以分号结尾都添加上 加上!!!。。。。。好吧 结果我们把eslint关了哎。。。)

3、 js 基本数据类型

字符串 string var const let

数值 Number Number()

真假 Boolean new Boolean()

数组 Array new Array() | []

对象 Object new Object | {}

NaN isNaN(a) //转成Number类型进行判断 so alert(isNaN("10")); //false(可以被转换成数值 10)

var num2 = Number(""); //0 var num4 = Number(true); //1 var num3 = Number("000011"); //11复制代码

what you find that ?

so not use Number use parseInt()

var num2 = parseInt(""); // NaN var num1 = parseInt("1234blue");// 1234    刚发现 666var num4 = parseInt(22.5); // 22 var num5 = parseInt("070"); // 56(八进制数)var num6 = parseInt("70"); // 70(十进制数)var num7 = parseInt("0xf"); // 15(十六进制数)复制代码

false 的8个值: ''

0、 - 0、 NaN、 false 、null、 undefined、 newBoolean()

问个问题:

[] === '' []== ''复制代码

结果是什么? why?

typeof 返回的是字符串, 有六种可能:

"number"、

"string"、

"boolean"、

"function"、

"undefined"、

"object": {

[],

{}

}

其中 null类型 typeof null === "object" 复制代码

so 判断变量是数组还是对象的时候 要过滤null。

eg:

if (isWaitting && isWaitting instanceof Array) {}复制代码

举个例子吧:

var shallowCopy = function(obj) { //一个浅拷贝方法应该知道为什么有这个方法吧 (数组、对象中地址引用的锅)if (typeof obj != 'object') return;var newObj = obj instanceof Array ? [] : {};for (var key in obj) {if (obj.hasOwnProperty(key)) {newObj[key] = obj[key];}}return newObj;}复制代码

再来个深拷贝: //记得gitHub 上有一个deep-assign npm可以install哦 有需要的大家可以搜下

var deepCopy = function(obj) {if (typeof obj !== 'object') return; //null NaN Mathvar newObj = obj instanceof Array ? [] : (!obj ? null : {});for (var key in obj) {if (obj.hasOwnProperty(key)) {newObj[key] = typeof obj[key] === 'object' ? deepCopy(obj[key]) :obj[key];}}return newObj;}复制代码

4、 在html引入js要注意的事项

肯定要写在 < script > < /script>里面喽!没话说的。如果浏览器不支持js的话 那用

<noscript ><p> 本页面需要浏览器支持( 启用) JavaScript。 </noscript>

我是至今也没见过浏览器显示这个的。 除非你把浏览器设置了不支持js语法。

这样当我没说!!

js一般引入的位置是在body后面而不是header里面。 因为浏览器渲染的过程中是单线程的。 当js加载完成并执行后才能继续往下加载别的。

一句话概括吧: 就是你他妈的js加载多的话,

入口页面渲染完成所用的时间过多, 体验不要。 嗯, 这个也引发了后面的前端优化什么的。 有点人说尽量不再js中改变dom节点的更改、 减少http的请求、

使用img snipe、 根据路由懒加载依赖的文件、 外部引用js文件的时候加defer( 这个属性的用途是表明脚本在执行时不会影响页 面的构造。也就是说, 脚本会被延迟到整个页面都解析完毕后再运行。 因此, 在 < script > 元素中设置 defer 属性, 相当于告诉浏览器立即下载,但延迟执行。

 )复制代码

拓展:

同样与 defer 类似,async 只适用于外部脚本文件, 并告诉浏览器立即下载文件。 但与 defer 不同的是, 标记为 async 的脚本并不保证按照指定它们的先后顺序执行。 例如:

在以上代码中, 第二个脚本文件可能会在第一个脚本文件之前执行。 因此, 确保两者之间互不依赖 非常重要。

指定 async 属性的目的是不让页面等待两个脚本下载和执行, 从而异步加载页面其他内容。

为此, 建议异步脚本不要在加载期间修改 DOM。 异步脚本一定会在页面的 load 事件前执行,但可能会在 DOMContentLoaded 事件触发之前或之 后执行。

支持异步脚本的浏览器有Firefox 3.6、 Safari5 和 Chrome

5、 来个运算符吧

var a = 0;a++;++a;复制代码

老生常谈了

var a = 0;a + +1 输出什么?//1 why?'' + 11 + '''1' + '2'1 + true输出什么?var num1 = 2;var num2 = 20;var num3 = --num1 + num2; // 输出什么?0.1 + 0.2 // 输出什么? 应该怎么做才能不丢失精度呢?考虑复制代码

6、 Boolean

以前常常看到人们判断一个变量是否为空 是否是没定义

if( a != null && typeof a != 'undefined') {}复制代码

忘了上面的‘ false 的8个值’ 了嘛? 今天以后就可以这样写

if(a) {} // a 不能是 0 -0 NaN '' false null undefined复制代码

特殊情况特殊对待

!!!a //强制转化a的类型为Boolean类型复制代码

追加:

a && b //短路运算 a如果为false 那么b不用判断了 懒!var c = a || 'fd' //默认赋值 a如果为false 那么c赋值为‘fd’ Infinity //了解下就行 我都没遇到过 无穷大--Infinity //无穷大的负数 你说是什么呢?for (;;) { // 无限循环 doSomething(); } for (true) { // 无限循环 doSomething(); } continue; break; //只能使用在循环遍历中 // foreach() map()里能用不 ?思考下 复制代码

7、 函数function

函数中的结束: return;

函数中没有java的重载。 只有替换

函数中没有类但能模拟类

//es5

var superClass = function() {this.name = null;}superClass.prototype.setName = function(name) {this.name = name;}superClass.prototype.getName = function() {return this.name;}var superC = new superClass();superC.setName('fd');superC.getName();var subClass = superClass.prototype; //继承subClass.prototype.mackSound = function() {this.name = '电风扇';}复制代码

//es6

class superClass2 {constructor() {this.name = name;}getName() {return this.name;}setName(name) {this.name = name;}show() {console.log(this.name);}}var as = new superClass2();as.setName('fdsf');as.show();class superClass3 extends superClass2 { //继承}var sdf = new superClass3();复制代码

8、闭包

(function sd() { console.log(12) })()//自动执行函数 复制代码

function adds() {var something = "ssh";var another = [1, 2, 3];function doSomething() {alert(something);}function doAnother() {alert(another.join(","));}return { doSomething: doSomething,doAnother: doAnother};}var fn = adds();fn.doSomething(); // coolfn.doAnother(); // 1 ! 2 ! 3//私有数据变量something和another,以及doSomething()和doAnother() 两个内部函数,//它们的语法作用域(而这就是闭包)也就是foo() 的内部作用域。复制代码

var a = (function() {var i = 0;return function() {return i++;}})()复制代码

var b = (function(name) {var i = 0;function identify() {alert(name.toUpperCase());}function add() {return i++;}return{identify:identify,add:add}})('ssh')复制代码

9、上下文执行环境 作用域

var a = 10;function sum(b) {return a + b;}function add() {var a = 20;var c = sum(30);return c;}add(); //40复制代码

why?为什么不是50呢?我的理解是:当函数没有执行前,函数中的变量就已经确定指向。比如sum()中 当没有调用add()方法的时候,sum()方法里的a已经的指针已经指向了全局作用域下定义的var a = 10;而非调用时候的var a = 20;

总结:函数创建的时候 就已经确定了作用域 . 要到创建这个函数的那个作用域中取值——是“创建”,而不是“调用”,切记切记.

上面描述的只是跨一步作用域去寻找。如果跨了一步,还没找到呢?——接着跨!——一直跨到全局作用域为止。要是在全局作用域中都没有找到,那就是真的没有了。

这个一步一步“跨”的路线,我们称之为——作用域链。

我们拿文字总结一下取自由变量时的这个“作用域链”过程:(假设a是自由量)

第一步,现在当前作用域查找a,如果有则获取并结束。如果没有则继续;

第二步,如果当前作用域是全局作用域,则证明a未定义,结束;否则继续;

第三步,(不是全局作用域,那就是函数作用域)将创建该函数的作用域作为当前作用域;

第四步,跳转到第一步。

var x = {name:'ssh',age:18}var fn = function(){console.log(this);console.log(this.name);}fn.call(x);//fn.apply(x)复制代码

//当一个函数被call和apply调用时,this的值就取传入的对象的值

既然说到了call apply 那就再继续说点吧

用call()apply() 可以强制指定this的指向。那么this又是什么玩意呢?代表当前作用域本身。在全局作用域下

在函数块级作用域下

这样应该明白了吧

有一天看到了一个这种写法

var arr = [1,2,4,5,7,34]Math.max.call(null,1,2,4,5,7,34) //34Math.max.apply(null,arr) //34复制代码

从上面可以看出两个东西:

1、call apply 接收参数的格式不同 怎么不同? 自己看

2、重新定义了Math.max函数的this指向

Es6:Math.max(...arr) //了解下就行。

上下文执行环境:就是当前函数执行时候所处的环境 环境应该都知道 java开发前都要先配置jre jdk开发环境 咱们的javascript中 函数运行时候也要有自己的环境。当一个函数执行完成后

当前上下文执行环境就会被销毁。至于涉及到堆栈方面的知识,技术有限,说不出来。。。。。想知道这样面的知识可以自行google。

10.地址引用遇到的坑

地址引用的数据类型有:array object

Var arr = [1,2];

自己理解:变量arr 中其实放的不是数据 1,2 。寄存的只是一个hash地址。该地址指向存放[1,2]的数据池。如果重新给arr赋值 arr = [1,3] 则arr指针重新指向了另一个数据池[1,3] 。

但是:当 var arr= [1,2] ;arr.push(4); 这时候指针是不变化的。变化的是指针定向的数据池里的数据。这点要注意。

记得有个面试题如下:

var arr = [1, 2, 3];var c = arr;arr = [1, 2];console.log(c); //[1, 2, 3]arr.push(4);console.log(arr); //[1, 2,4]console.log(c); //[1, 2, 3]var arr2= [1, 2, 3];var c2 = arr2;arr2.push(4);console.log(arr2); //[1, 2, 3,4]console.log(c); //[1, 2, 3]var obj = [{ name: 'ssh' }, { name: 'ssh2'}]var obj2 = [];obj.forEach((item, index) => {item.name == 'ssh' ? obj2.push(item) : false;})obj2[0].name = 'ssh2222';console.log(obj) // 有变化嘛如果有 why?复制代码

11、Math

常用的几种:

Math.abs() //返回数的绝对值。

Math.floor() //对数进行下舍入。 地板 懂?

Math.ceil() //对数进行上舍入。 天花板 懂?

Math. //返回 x 和 y 中的最高值。

Math.min(x,y)// 返回x 和 y 中的最低值。

Math. //返回 x 的 y 次幂。

Math. // 返回 0 ~ 1 之间的随机数。

Math. //把数四舍五入为最接近的整数。

Math.trunc(2.643) //2 截取小数点前面的数字

12、Date

Var a = new Date();本地全部时间格式:toLocaleString(); // "2017/11/16 下午4:27:09"a.toLocaleDateString() //"2017/11/16"toLocaleTimeString() // "下午4:27:09"getFullYear() //2017getTime()getTime() 返回从 1970 年 1 月 1 日至今的毫秒数。//+new Date()getDay()//如何使用 getDay() 和数组来显示星期几,而不仅仅是数字  //周日 =>0 ?复制代码

13、 Array 方法

主要几点就行了:

push pop 都是从数组后面开始处理数据的 (栈)shift unshift 从头开始 (队列)slice() 相当于重新定义了个数组 即不同的指针splice() //从数组中移除一个或多个数组,并用新的item代替他们 返回被替换的数组var a = ['a','b','c','d'];var b = a.splice(1,3,'f');a// ["a", "f"]b// ["b", "c","d"]复制代码

14、数组去重的正确编写姿势(面试很爱问!)

//使用数组的indexOf()方法可以很简单的达到目的。Array.prototype.unique = function() {// 创建一个新的临时数组,用于保存输出结果var n = []; // 遍历当前数组for (var i = 0; i < this.length; i++) {// 如果当前数组的第i个元素已经保存进了临时数组,那么跳过,否则把当前项push到临时数组里面if (n.indexOf(this[i]) == -1) n.push(this[i]);// if (!n.includes(this[i]))n.push(this[i]);}return n;}复制代码

最快姿势

//把已经出现过的元素通过下标的形式存入一个Object内。下标的引用的实现原理利用的是哈希算法,要比用indexOf()搜索数组快的多。Array.prototype.unique = function() {// n为hash表,r为临时数组var n = {}, r = [];for (var i = 0; i < this.length; i++) {// 如果hash表中没有当前项if (!n[this[i]]) {// 存入hash表n[this[i]] = true;// 把当前数组的当前项push到临时数组里面r.push(this[i]); }}return r;}复制代码

但从耗时的角度来讲,这是最优的一种解决方式。但是从内存占用角度来说,这并不是最优的,因为多了一个hash表。这就是所谓的空间换时间(世间安得双全法?)。

中庸姿势 //推荐

Array.prototype.unique = function() {this.sort();var re = [this[0]];for (var i = 1; i < this.length; i++) {if (this[i] !== re[re.length - 1]) {re.push(this[i]);}}return re;}复制代码

// [...new Set([1,1,3,4,3,56,6])] 最简单的方法复制代码

既然提到了new Set() 那么就延伸点别的吧

删除数组中指定的项:

Array.prototype.$remove = function (v) {const index = this.indexOf(v) //this代表数组本身if (index !== -1) this.splice(index, 1)return this;}const arr = [1, 2, 3]arr.$remove(2) //下标从1开始复制代码

Array.prototype.$delete = function (v){var set = new Set(this);// this 代表该数组本身set .delete(v);return [...set]}var arr = [1, 2, 3]arr.remove(2)// [1, 3]复制代码

es6 新添加了很多方法

如foreach、map 、filter 、reduce 、objectAssign 、copy、 includes 、indexof 、Array.isArray() 、Array.from() new Set() new Map() 等 。

在此不做详细的说明,想了解的可以自行google。

15、单线程中的异步

我们还经常遇到setTimeout(fn,0)这样的代码,0秒后执行又是什么意思呢?是不是可以立即执行呢?

答案是不会的,setTimeout(fn,0)的含义是,指定某个任务在主线程最早可得的空闲时间执行,意思就是不用再等多少秒了,只要主线程执行栈内的同步任务全部执行完成,栈为空就马上执行。

举例说明:

console.log('先执行这里');setTimeout(() => {console.log('执行啦1')},10);setTimeout(() => {console.log('执行啦2')},0);console.log('最后执行这里');复制代码

16、异步(重点 面试还是爱问!)

Promise:异步

下面是一个Promise对象的简单例子。

function timeout(ms) {return new Promise((resolve, reject) => {setTimeout(resolve, ms, 'done');});}timeout(100).then((value) => {console.log(value); //'done'});复制代码

上面代码中,timeout方法返回一个Promise实例,表示一段时间以后才会发生的结果。过了指定的时间(ms参数)以后,Promise实例的状态变为resolve,就会触发then方法绑定的回调函数。

Promise 实例

const wait = function(val) {    // 定义一个 promise 对象    const promise = new Promise((resolve, reject) => {            // 将之前的异步操作,包括到这个 new Promise 函数之内            const task = function() {                if (val) {                    console.log('执行完成');                    resolve(true)                } else { console.log('执行失败');                    reject(false) }                // callback 中去执行 resolve 或者 reject            }            setTimeout(task, 2000)        })        // 返回 promise 对象    return promise}const w = wait (1);var a = 0;w.then((val) => {    console.log('ok 1' + val);    a = 231;    console.log(a);    return w;}, (val) => {    console.log('err 1' + val)}).then((val) => {    console.log('ok 2' + val);    var b = a + 2;    console.log(b)}, (val) => {    console.log('err 2' + val)})复制代码

async :异步

依次读取两个文件:

var asyncReadFile = async function () {var f1 = await readFile('/etc/fstab');var f2 = await readFile('/etc/shells');console.log(f1.toString());console.log(f2.toString());};//注意 封装的readFile ()方法要返回promise对象async function getStockPriceByName(name) {var symbol = await getStockSymbol(name);var stockPrice = await getStockPrice(symbol);return stockPrice;}getStockPriceByName('goog').then(function (result) {console.log(result);});复制代码

使用注意点:

第一点,前面已经说过,await命令后面的Promise对象,运行结果可能是rejected,所以最好把await命令放在try...catch代码块中。

async function myFunction() {try {await somethingThatReturnsAPromise();} catch (err) {console.log(err);}}// 另一种写法 (推荐)async function myFunction() {await somethingThatReturnsAPromise().catch(function(err) {console.log(err);});}复制代码

因为以下所有的代码都会用到Promise,因此干脆在所有介绍之前,先封装一个Promise,封装一次,为下面多次应用。

const fs = require('fs')const path = require('path')  // 后面获取文件路径时候会用到const readFilePromise = function (fileName) {    return new Promise((resolve, reject) => {        fs.readFile(fileName, (err, data) => {            if (err) {                reject(err)  // 注意,这里执行 reject 是传递了参数,后面会有地方接收到这个参数            } else {                resolve(data.toString())  // 注意,这里执行 resolve 时传递了参数,后面会有地方接收到这个参数            }        })    })}复制代码

那么前面步骤return的值会被当做参数传递给后面步骤的函数,如下面代码中的a就接收到了return JSON.parse(data).a的值

const fullFileName = path.resolve(__dirname, '../data/data2.json')const result = readFilePromise(fullFileName)result.then(data => {    // 第一步操作    console.log(data)    return JSON.parse(data).a  // 这里将 a 属性的值 return}).then(a => {    // 第二步操作    console.log(a)  // 这里可以获取上一步 return 过来的值})复制代码

我们知道then会接收两个参数(函数),第一个参数会在执行resolve之后触发(还能传递参数),第二个参数会在执行reject之后触发(其实也可以传递参数,和resolve传递参数一样),但是上面的例子中,我们没有用到then的第二个参数。这是为何呢 ———— 因为不建议这么用。

对于Promise中的异常处理,我们建议用catch方法,而不是then的第二个参数。请看下面的代码,以及注释。

const fullFileName = path.resolve(__dirname, '../data/data2.json')const result = readFilePromise(fullFileName)result.then(data => {    console.log(data)    return JSON.parse(data).a;}).then(a => {    console.log(a)}).catch(err => {    console.log(err.stack)  // 这里的 catch 就能捕获 readFilePromise 中触发的 reject ,而且能接收 reject 传递的参数})复制代码

读取两个文件data1.json和data2.json,现在我需要一起读取这两个文件,等待它们全部都被读取完,再做下一步的操作。此时需要用到Promise.all。(以前记得做个打印报表的功能。当时报表数据差不多几万条。所以想到了分页打印。比如分5页,每页200条。那么打印的时候肯定要按顺序打印。即1-200,201-300以此打印。那么就写了个方法,循环遍历整个数据,每200条放到一个方法中,结果把5个方法再push到一个数组中。记得当时用的是$q 里面的all()方法来执行的。)

// Promise.all 接收一个包含多个 promise 对象的数组Promise.all([result1, result2]).then(datas => {    // 接收到的 datas 是一个数组,result1, result2 依次执行,返回包含了多个 promise的内容    console.log(datas[0])    console.log(datas[1])})  var funcA = function(){                console.log("funcA");                return "hello,funA";            }            var funcB = function(){                console.log("funcB");                return "hello,funB";            }          var a = [funcA ,funcB];          Promise.all([funcA , funcB]).then(datas => {   //  Promise.all(a).then()    // 接收到的 datas 是一个数组,依次包含了多个 promise 返回的内容    console.log(datas[0])    console.log(datas[1])})复制代码

读取两个文件data1.json和data2.json,现在我需要一起读取这两个文件,但是只要有一个已经读取了,就可以进行下一步的操作。此时需要用到Promise.race

// Promise.race 接收一个包含多个 promise 对象的数组Promise.race([result1, result2]).then(data => {// data 即最先执行完成的 promise 的返回值console.log(data)})复制代码

栗子:

var uploadQuestion = function(questions) {var promises = [];angular.forEach(questions, function(question) {var promise = $http({ //url: 'upload/question',method: 'POST',data: question});promises.push(promise);});return $q.all(promises);}复制代码

$q:异步

var iWantResolve = true;function es6promise() {    return $q(function(resolve, reject) {        $timeout(function() {            if (iWantResolve) {                resolve("es6promise resolved");            } else {                reject("es6promise reject");            }        }, 1000)    })}es6promise()    .then(function(data) {        console.log(data);    })    .catch(function(err) {        console.log(err);    });// if(iWantResolve == true) output: es6promise resolved// if(iWantResolve = false) output: es6promise reject复制代码

function commonJsPromise() {    var deferred = $q.defer();    $timeout(function() { //可以没有        deferred.notify("commonJS notify");        if (iWantResolve) {            deferred.resolve("commonJS resolved");        } else {            deferred.reject("commonJS reject");        }    }, 500);    return deferred.promise;}commonJsPromise()    .then(function /** success callback**/ (data) {        console.log(data);    }, function /** error callback **/ (err) {        console.log(err);    }, function /** progress callback **/ (update) {        console.log(update);    });// if(iWantResolve == true) output: commonJS notify commonJS resolved// if(iWantResolve = false) output: commonJS notify commonJS reject复制代码

$q.all([es6promise(), commonJsPromise()])    .then(function (dataArr) {        console.log("$q.all: ", dataArr);    }, function (err) {        console.log("$q.all: ", err)    }, function /** unnecessary **/ (update) {        console.log("$q.all", update);    });// if(iWantResolve == true) output: $q.all:  ["es6promise resolved", "commonJS resolved"]// if(iWantResolve = false) output: $q.all:  es6promise reject复制代码

大家都是到 jquery v1.5 之后$.ajax()返回的是一个deferred对象,而这个deferred对象和我们现在正在学习的Promise对象已经很接近了,但是还不一样。那么 ———— deferred对象能否转换成 ES6 的Promise对象来使用??

答案是能!需要使用Promise.resolve来实现这一功能,请看以下代码:

// 在浏览器环境下运行,而非node 环境

const jsPromise =Promise.resolve($.ajax('/whatever.json'))jsPromise.then(data => {// ...})//ajax 异步执行方法复制代码

其实,在我们的日常开发中,这种将thenable转换为Promise的需求并不多。真正需要的是,将一些异步操作函数(如fs.readFile)转换为Promise(就像文章一开始readFilePromise做的那样)而且then必须返回一个promise,同一个 promise 的then可以调用多次(链式)” ——— 这两句话说明了一个意思 ——— then肯定要再返回一个promise,要不然then后面怎么能再链式的跟一个then呢?

const w9991 = wait(1)w9991.then((val) => {console.log('ok 1'+val);// ok 1true ok 2true //2不是undefinedreturn w9991;}).then((val) => {console.log('ok 2'+val); })复制代码

eg:

function readFilePromise() {    return new Promise((resolve, reject) => {        resolve(setTimeout(() => {            console.log(1111);        }));    })};const readFileAsync = async function() {        const f1 = await readFilePromise();        const f2 = await readFilePromise();        return 'done' // 先忽略,后面会讲到    }    // 执行const result = readFileAsync() //1111 1111result.then(data => {    console.log(data) // done})复制代码

使用async-await的不同和好处

第一,await后面不能再跟thunk函数,而必须跟一个Promise对象(因此,Promise才是异步的终极解决方案和未来)。跟其他类型的数据也OK,但是会直接同步执行,而不是异步。

第二,执行const result = readFileAsync()返回的是个Promise对象,而且上面代码中的return 'done'会直接被下面的then函数接收到

result.then(data => {console.log(data) // done})复制代码

第三,从代码的易读性来将,async-await更加易读简介,也更加符合代码的语意。而且还不用引用第三方库,也无需学习Generator那一堆东西,使用成本非常低。

总结:

异步操作 : promise \generator yield \async-await\$q

17、正则

这个我只会简单的就不在此卖弄了。。。呵呵哒

18、window 对象(html5 api)

下期见。。。

19、模块化封装方法(exports、 module exports 、export default)

下期见。。。

总结: 文章穿插有点大 .都是笔者随心写的。第一次写,如有错误请指正。请多多关照!!呵呵哒.

备注:文章有些是以前的学习笔记,直接拷贝上来的。侵删!

转载地址:http://fihpl.baihongyu.com/

你可能感兴趣的文章
Copy修饰的NSArray
查看>>
eclipse新建web项目
查看>>
gnuplot
查看>>
GraphQL(三):GraphQL集成SpringBoot原理
查看>>
Balloons
查看>>
posix消息队列(1)
查看>>
using for jekyll
查看>>
Jenkins的授权和访问控制
查看>>
C/C++里的const(1)
查看>>
Expert 诊断优化系列-------------针对重点语句调索引
查看>>
解决Run As -> Java Application不能运行问题
查看>>
JSP 注释的详解及简单实例
查看>>
c:\Windows\System32\drivers\etc\hosts的作用
查看>>
2.Xml与多个对象的映射(聚合或组合)及注意事项
查看>>
java报表开发之报表总述
查看>>
正确释放Vector的内存
查看>>
【零基础学习iOS开发】【02-C语言】04-常量、变量
查看>>
最小堆的基础操作(Java)
查看>>
bzoj2039: [2009国家集训队]employ人员雇佣(最小割)
查看>>
AspNetCore Mvc 使用 PartialView
查看>>