中国最好的网站建设,南京做网站哪家公司好,wordpress文章运行php,wordpress安装畅言此文章主要讲解核心思想和基本用法#xff0c;想要了解更多细节全面的使用方式#xff0c;请阅读官方API 这篇文章假定你具备最基本的异步编程知识#xff0c;例如知道什么是回调#xff0c;知道什么是链式调用#xff0c;同时具备最基本的单词量#xff0c;例如page、us…此文章主要讲解核心思想和基本用法想要了解更多细节全面的使用方式请阅读官方API 这篇文章假定你具备最基本的异步编程知识例如知道什么是回调知道什么是链式调用同时具备最基本的单词量例如page、user、promise、then、resovle、reject、pay、fix、order等等如果你对这些单词非常陌生那么你需要先花点时间补充一下你的英语什么是异步操作所谓异步操作指的是可以跟当前程序同时执行的操作。举例:$(#page).scrolltop(0 ,1000); //使用1秒钟时间将页面滚动至顶部
$(#nav-float).hide (1000); //使用1秒钟时间将悬浮导航栏隐藏只要你稍微有点异步编程经验就应该知道这两个方法会同时完成。它们的编写顺序并不会影响它们的执行顺序//异步操作的特点就是不会打断当前程序的执行//getUsers请求发出后会立刻向下继续执行第二个请求
ajax(/getUsers,function(data) {//回掉函数会在请求成功后调用
})
//resumelist请求会立刻开始无论getUsers是否结束
ajax(/resumelist, function(data) {})
//至于哪一个ajax先返回结果并执行回调函数从代码的编写顺序上是无法确定的。我们可以给异步操作做一个简单的定义当一个操作开始执行后主程序无需等待它的完成可以继续向下执行。此时该操作可以跟主程序同时并发执行。这种操作我们就称之为异步操作。 通常当操作完成时会执行一个我们事先设定好的回调函数来做后续的处理。我们常见的异步操作例如添加定时器 setTimeout/setInterval执行某个动画 animate发起网络请求 request异步会带来什么问题比如我们现在有两个动画需要按顺序来执行也就是第一个结束第二个才能开始 这个时候可能有点麻烦传统的解决方法是通过回调animateA(function( ){animateB( );
}) 这种方案显然不太好如果有很多异步操作需要顺序执行就会产生所谓的“回调地狱”ajaxA(function( ){ajaxB(function( ){ajaxC(function( ){ajaxD(function( ){...... }); }); });
}) 这种代码不管是写起来还是读起来都比较烦人。我们来看下经过Promise改造后的样子伪代码newPromise(ajaxA).then(ajaxB).then(ajaxC).then(ajaxD); Promise的使用及原理要熟练Promise的的使用你必须要先搞懂它解决问题的原理 贴一段实际的Promise代码你来感受一下先newPromise(resolve{ajax(/pay/post, dataresolve() );
}).then(resolve{ajax(/order/fix, data{//处理数据 })
})上面的代码使用了ES6的箭头函数,虽然大大简化了代码的写法但对于初级程序猿来讲极不友好读这种代码简直跟读金刚经差不多。我们把代码还原成ES5的样子newPromise(function(resolve){ajax(/pay/post,function(data){resolve();})
}).then(function(){ajax(/order/fix,function(data){})
})接下来我们就按照费曼技巧来一步步的学习Promise是如何解决问题的问题1, 作为一个异步函数尤其像ajax这种网络请求连我自己都不能确定函数的执行时间Promise是怎么知道第一个函数什么时候结束的 然后再开始执行下一个Promise并没有那么神奇它并不能知道我们的函数什么时候结束
你注意到上面代码中的第3行了吗
在ajax请求结束执行回调的时候
我们调用了一个resolve()函数这句代码非常的关键.
这其实就是在通知Promise当前这个函数结束啦
你可以开始执行下一个。 这时Promise就会去执行then里面的函数了。问题2, 所以按照你的意思如果我不调用这个方法Promise就不知道这个函数有没有结束那么then里面的函数就不会执行也就是说我的第二个请求就永远不会发送了呗Bingo!! 恭喜你已经学会了逻辑推理抢答。问题3, 可是这个resolve函数是从哪来的 需要我自己定义吗 从代码上看它好像是个参数那又是谁传入函数中的你得先弄明白Promise的基本结构
newPromise(函数1).then(函数2);我们把函数1和函数2都以参数形式传给了一个Promise对象
所以接下来函数1和2都会由这个Promise对象控制
简单的说函数1和函数2都会由Promise对象来执行。
所以在函数1执行时参数也当然是由Promise对象传递进去的。newPromise(function(resolve){//resolve是Promise对象在调用函数时传入的参数
}).then(函数2);问题4, Promise对象为啥要在执行第1个任务的时候把这个resolve函数 传进来有什么目的你说呢废屁知道还用问你真是猪脑子刚才不是已经说了吗
Promise对象没办法知道我们的异步函数啥时候结束。
那我来问你 如果你去车站接人
可是你又不知道对方何时下车你会咋办把我电话号码给他快到了打我电话呗没错Promise解决问题也采用了同样的思路。
它传进来的resolve函数 就好像一个对讲机
当我们的异步任务要结束时通过对讲机 来通知Promise对象。
也就是调用resolve方法newPromise(function(resolve){ajax(/pay/post,function(data){//当请求结束时通过调用resolve方法通知Promise对象该任务已完成resolve(); //收到通知后Promise会立刻开始函数2的执行})
}).then(函数2);懂了所以这个resolve函数必须在异步任务的最后调用(例如ajax的回调方法)相当于告诉Promise对象该任务结束请开始下一个。完全正确问题5, 所以Promise也不过如此嘛它没有带来什么功能上的革命性变化 因为使用传统的回调嵌套的方式同样可以完成效果。 说白了它就是编码方式上的改进基本是这样的但Promise带来的编码方式以及异步编程思路上的进步是非常巨大的。问题6, 那如果我有ajaxA、ajaxB、ajaxC三个异步任务想按照先A后B再C的顺序执行像这样写行吗newPromise(function(resolve){ajax(/AAA, function(){resolve(); //通知Promise该任务结束})
}).then(function(resolve){ajax(/BBB, function(){resolve();//通知Promise该任务结束})
}).then(function(){ajax(/CCC, function(){ //.... })
}) 上面的这种写法是不对的。
Promise的中文含义是“承诺”
则意味着每一个Pormise对象代表一次承诺
而每一次承诺只能保证一个任务的顺序也就是说
newPromise(A).then(B); 这句话表示 只能保证A和B的顺序一旦A执行完B开始后这次承诺也就兑现了Promise对象也就失效了
那如果还有C呢 我们就必须在函数B中
重新创建新的Promise对象来完成下一个承诺具体的写法就像这样newPromise(函数1(resolve){ajaxA(xxxx, function(){resolve();//通知Promise该任务结束})
}).then(函数2(){//在函数2开始运行后第一次创建的Promise对象完成使命已经不能再继续工作。//此时我们创建并返回了新的Promise对象returnnewPromise(function(resolve){ajaxB(xxxx, function(){resolve();//通知新的Promise对象该任务结束}) })
}).then(函数3(){ //尽管这里使用了链式调用但负责执行函数3的已经是新的Promise对象了// 如果我们还有ajaxD需要顺序调用// 那就必须在这里重新new Promise()对象了ajaxC(xxx, function(){ })
}) 问题7, 懂了那Promise还有什么其它强大的功能吗有啊例如 如果我有 A,B,C 三个异步任务ABC同时开始执行
当A,B,C三个任务全部都结束时执任务D
传统方法实现起来就比较复杂Promise就非常简单就像这样Promise.all([newPromise(A), newPromise(B), newPromise(C)])
.then(function(){D();
});问题8, 那如果我希望A,B,C 其中任意一个任务完成 就马上开始任务D该怎么做Promise.race([newPromise(A), newPromise(B), newPromise(C)])
.then(function(){D();
});