最近越来越喜欢与大家进行资源分享了,并且及时的同步到自己的园子内,为什么呢?

一、小插曲(气氛搞起)

在上个月末,由于领导的高度重视(haha,这个高度是有多高呢,185就好了),走进了公司骨干员工的队列,并参与为骨干员工准备的“高效能人士的七项修炼”课程培训。

那接下来我是不是该简明扼要的说一下七项修炼有哪些,很受用哦。

七项修炼之一:积极主动 ==> 积极心态去处理事情、不怕事。

七项修炼之二:明确方向 ==> 要做到以终为始,将终点作为起点,帮助你实现生活与工作中的重要目标。

七项修炼之三:要事优先 ==> 主要针对时间安排、轻重事的划分,可以参考以下象限图。

第一象限:重要且紧急的事情放到首位去解决,这个象限的事情不做那你就真傻咯,等着被炒吧  2333333。

第二象限:有些事情是重要但不紧急的,一定不能拖,拖久了这件事情会变成紧急并且重要,这样下来你就永远在处理重要且紧急的事情,所以说处理完第一象限赶紧处理第二象限的。

第三象限:有些事情是特别紧急但不重要的,总会去占用你的时间去处理,并且对你没有什么意义,像这类没有意义、对你影响不大的事情就可以直接丢掉了,或者交给你的下属去处理。

第四象限:该象限就可以想而知了,不重要、不紧急,所以坚决不做。

七项修炼之四:双赢思维 ==> 是指 “我们” 而非 “我”,一起寻求互惠思考与心意,目的是获得更丰富的机会,财富及资源,而非患不足的敌对式竞争,还必须做到高勇气高体谅哦。

七项修炼之五:知彼解己 ==> 学会如何去沟通,80%的沟通障碍来自于听(聽==>以耳为王,十目一心),一定要带着理解对方的目的去倾听。

七项修炼之六:协作增效 ==> 三个臭皮匠顶个诸葛亮、瞎子背瘸子的故事大家都听过吧,那如何实现1+1>2呢?(仔细体会吧)。

七项修炼之七:不断更新 ==> 有了前六项了,当然要不断地更新、完善提升自己了。

最后借鉴Samuel Smiles的一句话送给大家:“思想引发行为,行为渐成习惯,习惯塑造品格,品格决定命运”。

以上讲了一堆自己培训之后的小感悟,小收获吧。

二、步入正文,什么是Promise,能够解决什么问题?

我们知道,JavaScript的执行环境是单线程,所谓的单线程是指一个任务执行完成之后才可以执行下一个任务,如若某一个任务执行出错,会导致下一个任务无法执行。但是在JavaScript中也提供了一些异步模式。

以下是两段特别经典的异步模式:

function setTime(callback){
setTimeout(()=>{
callback();
console.log("我被最后输出,惨那。");
},0);
console.log("异步执行代码。");
};
setTime(()=>{
console.log("多会可以执行我呢?");
}); //异步执行代码。
//多会可以执行我呢?
//我被最后输出,惨那。
function getData(url,callback, errorCallback) {
$.ajax({
url: url,
success: function (res) {
//成功函数
callback(res);
},
fail: function (res) {
//失败函数
errorCallback(res);
}
});
} getData("../url/url",(res)=>{
console.log("请求成功回调。");
},(res)=>{
console.log("请求失败回调。");
})

上面的两段代码看起来貌似没有什么问题。

是的,并不存在什么问题。但是在需求的代码化中,这样的异步模式往往会出现嵌套的形式,那它的展现形式如下。

setTime(()=>{
setTime(()=>{
setTime(()=>{
setTime(()=>{ });
});
});
console.log("多会可以执行我呢?");
});
getData("../url/url",(res)=>{
getData("../url/url",(res)=>{
console.log("请求成功回调。");
},(res)=>{
console.log("请求失败回调。");
})
console.log("请求成功回调。");
},(res)=>{
console.log("请求失败回调。");
})

类似这样的层层嵌套,它的执行顺序就不好把握了,维护性以及可读性也就可想而知了。重要的是回调函数剥夺了我们使用 return 和 throw 这类关键字的能力。

1.说了这么多,我们的Promise该闪亮登场了✨,Promise 很好的解决以上全部问题,是异步编程的一种解决方案,它由社区最早提出和实现,ES6将其写进了语言标准,统一了用法,原生提供了 Promise 对象。

所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。

Promise对象有两个特点:

1】Promise对象的状态不受外界影响。Promise对象存在三种状态:pending(进行中)、fulfilled(已成功)和reject(已失败),只有异步操作的结果,可以决定是哪一种状态,任何其他操作都无法发变这个状态。

这也就是Promise这个名字的由来。他的英文意思就是“承诺”,表示通过其他手段无法改变。

2】一旦状态改变,就不会再变,任何时候都可以得到这个结果。

Promise对象的状态改变,只有两种可能:从pending变为fulfilled和从pending变为rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果,这时就称为 resolved(已定型)。如果改变已经发生了,你再对Promise对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。

Promise也有一些缺点。首先,无法取消Promise,一旦新建它就会立即执行,无法中途取消。其次,如果不设置回调函数,Promise内部抛出的错误,不会反应到外部。第三,当处于pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。

2.基本用法:

ES6规定,Promise 对象是一个构造函数,用来生成Promise 实例。

下面的代码就是一个Promise 实例:

var promise=new Promise(function(resolve,reject){
//code
if(/*异步操作*/){
resolve();
}else{
reject();
}
})

Promise构造函数接受一个函数作为参数,该函数有两个参数分别是resolve和reject,它们也是函数。

resolve函数的作用是,将Promise 对象的状态从“未完成”(pending)==>“成功”(resolved),在异步操作成功时调用,并将异步操作结果,作为参数传递出去。

reject函数的作用是,将Promise 对象的状态从“未完成”(pending)==>“失败”(rejected),再异步操作失败时调用,并将操作报错的错误,作为参数传递出去。

Promise实例生成以后,可以用then方法分别指定resolved状态和rejected状态的回调函数。

promise.then(function(value) {
// success
}, function(error) {
// failure
}); 等同于
promise.then(
value=>{
// success
},
error=> {
// failure
}
);

then方法可以接受两个回调函数作为参数。第一个回调函数是Promise对象的状态变为resolved时调用,第二个回调函数是Promise对象的状态变为rejected时调用。其中,第二个函数是可选的,不一定要提供。这两个函数都接受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实例的状态变为resolved,就会触发then方法绑定的回调函数。

Promise 新建后就会立即执行。

var promise = new Promise(function(resolve, reject) {
console.log('Promise');
resolve();
}); promise.then(function() {
console.log('resolved.');
}); console.log('Hi!'); // Promise
// Hi!
// resolved

上面代码中,Promise 新建后立即执行,所以首先输出的是Promise。然后,then方法指定的回调函数,将在当前脚本所有同步任务执行完才会执行,所以resolved最后输出。

3.then用法:前面说过,then方法的第一个参数是resolved状态的回调函数。第二个参数(可选)是rejected状态的回调函数。

var promise=new Promies(function(resolve,reject){
if(/*异步执行成功*/){
resolve();
}else{
reject();
}
}) promise().then(
res=>{
console.log(res);
},error=>{
console.log(error);
}
)

因此可以采用链式写法,即then后在调用另一个then方法。

promise()
.then((res)=>{
//code
return res.a;
})
.then((res)=>{
//code
return res.b;
})
.then((res)=>{
//code
return res.c;
})

上面的代码使用then方法,依次指定了两个回调函数。第一个回调函数完成以后,会将返回结果作为参数,传入第二个回调函数。

4.catch用法:是用于指定发生错时的回调函数,即为Promise从未完成到失败的回调函数。

下面是这个例子。

var promise = new Promise(function(resolve, reject) {
reject();
});
promise.catch(function(error) {
console.log(error);
});
// Error: test

另外,then方法指定的回调函数,在运行中抛出错误时,也会被catch方法捕获。

var promise = new Promise(function(resolve, reject) {
throw new Error('test');
});
promise.catch(function(error) {
console.log(error);
});
// Error: test

上面代码中,promise抛出一个错误,就被catch方法指定的回调函数捕获。

如果 Promise 状态已经变成resolved,再抛出错误是无效的。

const promise = new Promise(function(resolve, reject) {
resolve('ok');
throw new Error('test');
});
promise
.then(function(value) { console.log(value) })
.catch(function(error) { console.log(error) });
// ok

上面代码中,Promise 在resolve语句后面,再抛出错误,不会被捕获,等于没有抛出。因为 Promise 的状态一旦改变,就永久保持该状态,不会再变了。

Promise 对象的错误具有“冒泡”性质,会一直向后传递,直到被捕获为止。也就是说,错误总是会被下一个catch语句捕获。

getJSON('/post/1.json').then(function(post) {
return getJSON(post.commentURL);
}).then(function(comments) {
// some code
}).catch(function(error) {
// 处理前面三个Promise产生的错误
});

上面代码中,一共有三个 Promise 对象:一个由getJSON产生,两个由then产生。它们之中任何一个抛出的错误,都会被最后一个catch捕获。

一般来说,不要在then方法里面定义 Reject 状态的回调函数(即then的第二个参数),总是使用catch方法。

// bad
promise
.then(function(data) {
// success
}, function(err) {
// error
}); // good
promise
.then(function(data) { //cb
// success
})
.catch(function(err) {
// error
});

上面代码中,第二种写法要好于第一种写法,理由是第二种写法可以捕获前面then方法执行中的错误,也更接近同步的写法(try/catch)。因此,建议总是使用catch方法,而不使用then方法的第二个参数。

5. all用法:提供了并行执行异步操作的能力,并且在所有异步操作完成后才执行回调函数 ==> 【谁跑的慢,以谁为准执行回调】。

看下面例子:

function runAsync1(){
var p = new Promise(function(resolve, reject){
//做一些异步操作
setTimeout(function(){
console.log('异步任务1执行完成');
resolve('随便什么数据1');
}, 1000);
});
return p;
}
function runAsync2(){
var p = new Promise(function(resolve, reject){
//做一些异步操作
setTimeout(function(){
console.log('异步任务2执行完成');
resolve('随便什么数据2');
}, 2000);
});
return p;
}
function runAsync3(){
var p = new Promise(function(resolve, reject){
//做一些异步操作
setTimeout(function(){
console.log('异步任务3执行完成');
resolve('随便什么数据3');
}, 2000);
});
return p;
} Promise.all([runAsync1(),runAsync2(),runAsync3()]).then((res)=>{ }) //异步任务1执行完成
//异步任务2执行完成
//异步任务3执行完成
//["随便什么数据1","随便什么数据2","随便什么数据3"]

用Promise.all来执行,all接收一个数组作为参数,里面的值最终会返回Promise对象。这样三个异步操作的并行执行,等到它们都执行完后才会进入then里面。all会把三个异步操作的结果放到一个数组中传给then。也就是说有了all,你就可以并行执行多个异步操作,并且在一个回调函数中处理所有异步操作返回的数据。是不是炫酷吊炸天?有一个场景很适用这个,在素材比较多的应用,预先加载需要用到的各种资源,所有加载完后,我们在进行页面的初始化。

6.race用法:同样是并行异步操作,与all方法不同的是,率先完成异步操作的就立马执行回调函数 ==> 【谁跑的快,以谁为准执行回调】。

function runAsync1(){
var p = new Promise(function(resolve, reject){
//做一些异步操作
setTimeout(function(){
console.log('异步任务1执行完成');
resolve('随便什么数据1');
}, 1000);
});
return p;
}
function runAsync2(){
var p = new Promise(function(resolve, reject){
//做一些异步操作
setTimeout(function(){
console.log('异步任务2执行完成');
resolve('随便什么数据2');
}, 2000);
});
return p;
}
function runAsync3(){
var p = new Promise(function(resolve, reject){
//做一些异步操作
setTimeout(function(){
console.log('异步任务3执行完成');
resolve('随便什么数据3');
}, 2000);
});
return p;
} Promise.all([runAsync1(),runAsync2(),runAsync3()]).then((res)=>{ }) //异步任务1执行完成
//随便什么数据1
//异步任务2执行完成
//异步任务3执行完成

在then里面回调开始执行时,runAsync2()和runAsync3()并未停止,仍旧再执行,于是1秒后,输给了他们的结束标志。

总结:ES6 Promise 的内容就这些么? 是的,能用到的基本就是这些。

关于Promise 就说这些了,有疑问随时留言哦,有不对之处,请指正。谢谢。

引用阮大神:http://es6.ruanyifeng.com/#docs/promise



ES6 Promise 异步操作的更多相关文章

  1. Es6 Promise 用法详解

     Promise是什么??    打印出来看看  console.dir(Promise) 这么一看就明白了,Promise是一个构造函数,自己身上有all.reject.resolve这几个眼熟的方 ...

  2. 解析ES6 Promise

    ES6 Promise 概念之类的,大概读者都应该有所知道,接下来我们直入终点. 先让我们来看看什么是Promise吧,他是一个object,类,arry,function? 首先,学习它的时候应该讲 ...

  3. jquery Promise和ES6 Promise的区别

    1. Deferred对象有resolve和reject方法,可以直接修改状态 jquery用Deferred实现了Promise规范,Deferred与ES6 Promise的最大区别是: Defe ...

  4. es6 promise 所见

    一.Promise是什么? Promise 是异步编程的一种解决方案: 从语法上讲,promise是一个对象,从它可以获取异步操作的消息:从本意上讲,它是承诺,承诺它过一段时间会给你一个结果. pro ...

  5. [转载]es6 Promise.resolve()方法

    es6 Promise.resolve()方法 2018-01-27 22:29:06 ixygj197875 阅读数 16925更多 分类专栏: ES6标准入门 (阮一峰) ES6标准入门   Pr ...

  6. 通过 ES6 Promise 和 jQuery Deferred 的异同学习 Promise

    Deferred 和 Promise ES6 和 jQuery 都有 Deffered 和 Promise,但是略有不同.不过它们的作用可以简单的用两句话来描述 Deffered 触发 resolve ...

  7. ES6 Promise 接口

    构造函数 new Promise(function(resolve, reject){}); 构造函数接受一个函数(executor)作为参数,该函数在返回 Promise 实例之前被调用.函数的两个 ...

  8. ES6 Promise 全面总结

    转载:点击查看原文 ES6 Promise对象 ES6中,新增了Promise对象,它主要用于处理异步回调代码,让代码不至于陷入回调嵌套的死路中. @-v-@ 1. Promise本质 Promise ...

  9. 微信小程序Http高级封装 es6 promise

    公司突然要开放微信小程序,持续蒙蔽的我还不知道小程序是个什么玩意. 于是上网查了一下,就开始着手开发..... 首先开发客户端的东西,都有个共同点,那就是  数据请求! 看了下小程序的请求方式大概和a ...

随机推荐

  1. Expo大作战(四十)--expo sdk api之 Calendar,Constants

    简要:本系列文章讲会对expo进行全面的介绍,本人从2017年6月份接触expo以来,对expo的研究断断续续,一路走来将近10个月,废话不多说,接下来你看到内容,讲全部来与官网 我猜去全部机翻+个人 ...

  2. (后端)shiro:Wildcard string cannot be null or empty. Make sure permission strings are properly formatted.

    访问某页面时,出现了这个异常: java.lang.IllegalArgumentException: Wildcard string cannot be null or empty. Make su ...

  3. js判断IE浏览器及版本

    function isIE(_version){ _version = _version || ''; var b = document.createElement('b'); b.innerHTML ...

  4. SQL Server 中的回滚

    USE [TestDB] GO /****** 对象: Table [dbo].[Person] 脚本日期: 11/23/2008 13:37:48 ******/ SET ANSI_NULLS ON ...

  5. C++基础学习一(基础之基础)

    开篇:做了这么多年的软件,第一次使用博客的方式记录学习过程,之前都是笔记本(都有一摞了),因为之前一直从事的都是.NET的开发工作,对C++知之甚少,但一直想了解C++这门鼻祖级的语言,现在终于下定决 ...

  6. Spring 12 种 常用注解!

    1.声明bean的注解 @Component 组件,没有明确的角色 @Service 在业务逻辑层使用(service层) @Repository 在数据访问层使用(dao层) @Controller ...

  7. C#中类为什么要实例化

    在使用C#语言时,发现一下有关类实例化的问题,在此之前先复习一下类和对象的概念,类是一个抽象体,是对一类事物的抽象体:而对象就是一个具体的事物,对象的抽象就是类.车就是一个类,而车包括面包车,小汽车, ...

  8. February 4th, 2018 Week 6th Sunday

    Hope clouds observation. 心怀希望会蒙蔽双眼,影响判断. Almost every of us thinks we would be the master of our liv ...

  9. January 04th, 2018 Week 01st Thursday

    Just do what works for you, because there will always be someone who think differently. 就做你自己所能做的,因为 ...

  10. zTree异步加载展开第一级节点

    在 setting 中的 callback 中加上 onAsyncSuccess:onAsyncSuccess 回调函数 , 然后实现回调函数 var isFirst = true;function ...