解决异步 Promise Generator async/await
Promise https://www.jianshu.com/p/b4f0425b22a1
https://segmentfault.com/a/1190000015938472
http://fex.baidu.com/blog/2015/07/we-have-a-problem-with-promises/
promises 的奇妙在于给予我们以前的 return
与 throw
。但是在实践中这到底是怎么一回事呢?
每一个 promise 都会提供给你一个 then()
函数 (或是 catch()
,实际上只是 then(null, ...)
的语法糖)。
Promise
有三种状态:pending/reslove/reject 。pending就是正在执行,resolve可以理解为成功,reject可以理解为拒绝。
Promise 构造函数有两个变量 resolve
用于返回异步执行成功的函数, reject
用于返回异步执行失败的函数。配合then与catch一起使用
resolve函数的作用是将Promise对象的状态由Pending变为Resolved, 在异步操作成功时,将操作结果作为参数传递出去;
reject函数的作用是将Promise对象的状态由Pending变为Rejected,在异步操作失败时调用,并将异步操作的错误作为参数传递出去.
function f() {
let promise = new Promise((resolve, reject) => {
//模拟异步
setTimeout(()=>{
resolve('prom')
},1000)
})
return promise;
}
Promise.all( 传入一个数组,每一项分别是一个Promise实例 ), 当数据里的Promise状态都变为resolve时, Promise.all状态才变为resolve。只要有一个Promise的状态变为reject, Promise.all就变为reject; 可以将数组里的Promise看成是 "与" 关系
Promise.race( 传入一个数组,每一项分别是Promise实例 ), 与Promise.all相反, race可以看到 是 "或" 关系, 只要有一个Promise状态变为resolve, Promise.all 就变为resolve
Promise.resolve(): 将现有对象转为Promise对象
(1) 参数是一个Promise实例,不做任何变动,返回原对象
(2) 参数是一个具有then方法的对象,Promise.resolve方法会将这个对象转为Promise对象, 然后立即执行该对象的then方法
(3) 参数不具有then方法, 或者根本不是对象. Promise.resolve方法返回一个新的Promise对象, 状态为Resolve
(4) 不带任何任何参数, Promise.resolve方法直接返回一个Resolve状态的Promise对象
Promise.reject(): 返回一个新的Promise实例,该实例状态为reject; 参数用法与Promise.resolve()方法完全一致
注意 Promise.resolve(返回的数据将成为下一个then函数中的参数)
研究了两天,才终于写出来。而且明明就几行代码的事,感觉自己好笨.......好在学会了控制异步,找回了学习状态...继续加油吧
可以参考慕课网视频 https://www.imooc.com/video/16614
有一个很经典的讲解,里面还包括出现的问题:We have a problem with promises.链接:http://fex.baidu.com/blog/2015/07/we-have-a-problem-with-promises/ 注意,没有return时是忽略then内的执行方法的
我的工程代码:(只有return Kelp.jsonPost()时才会在ajax执行完后继续,否则会跳过ajax异步方法 )
new Promise((resovle, reject)=> {
return Kelp.jsonPost("../func/web/getBirdOrderOptionList",
null,function(result){ //必须有return
if (result.re == "1" || result.re == 1) {
var orderOptionList = result.data.orderOptionList;
for(var i=0;i<orderOptionList.length;i++){
var option = document.createElement("option");
$(option).val(orderOptionList[i].value);
$(option).text(orderOptionList[i].label);
$('#order').append(option);
}
console.log("orderfinished");
resovle("orderGet"); //在数据处理正常完成后调用这个方法,promise状态变为fulfilled。resovle 不要写错成resolve,这里resovle 内参数是给后续then传的值。当promise函数状态改变时,会立刻出发then函数并作相应处理
}
})
}
)
//鸟科
.then( value=> {
console.log(value);
return new Promise(resovle => {
return Kelp.jsonPost(
"../func/web/getBirdFamilyOptionList",null,function(result){
if (result.re == "1" || result.re == 1) {
familyOptionList = result.data.familyOptionList;
for(var i=0;i<familyOptionList.length;i++){
var option = document.createElement("option");
$(option).val(familyOptionList[i].value);
$(option).text(familyOptionList[i].label);
$('#catalogId').append(option);
}
console.log(" familyfinished");
resovle("familyGet");
}
})
})
})
Generator
https://blog.csdn.net/qq_21602341/article/details/87820778
如果过多的使用then 也会照成新的执行流程问题。所以我们的另一位主角登场了,那就是ES6中的Generator
(生成器)
Generator
(生成器)是一种有效利用内存的机制,一边循环一边计算生成数值的机制。通过配合Promise可以更加优雅的写异步代码
async/await
处理异步
https://www.cnblogs.com/SamWeb/p/8417940.html
先说一下async的用法,它作为一个关键字放到函数前面,用于表示函数是一个异步函数,因为async就是异步的意思, 异步函数也就意味着该函数的执行不会阻塞后面代码的执行。 写一个async 函数
async function timeout() {
return 'hello world';
}
async 函数返回的是一个promise 对象
我的代码:
//项目对应学生数剩余名额
function getProjectStudentMaxQuota(){
return new Promise(resolve => {
Kelp.jsonPost("../func/web/checkProjectStudentMax", null,
function (result) {
let hasQuotaNum = 0;
if (result.re === 1) {
hasQuotaNum = result.data.hasQuotaNum;
}
console.log("before--- hasQuotaNum="+hasQuotaNum);
resolve(hasQuotaNum);
// return hasQuotaNum;
})
})
}
//通过审核学生,需判断是否有剩余名额
$('#tbody').on('click','#passBtn', async function (e) {
let hasQuotaNum = await getProjectStudentMaxQuota();
console.log("after---");
if (typeof (hasQuotaNum) != "undefined" && hasQuotaNum > 0) {
if (hasQuotaNum == 1) {
//通过此学生会拒绝所有正在申请人
if (confirm("点击通过会默认拒绝该项目其他学生请求,是否继续操作?")) {
e = e || window.event;
let elem = e.target || e.srcElement;
let personId = elem.value;
updateStudentProjectApplyState(personId, 1, hasQuotaNum);
} else
return false;
} else { //直接通过
e = e || window.event;
let elem = e.target || e.srcElement;
let personId = elem.value;
updateStudentProjectApplyState(personId, 1, hasQuotaNum);
}
} else {
alert("您所能选择的学生数已达到最大,无法继续通过");
return false;
}
})