首先 必须明确几点
- 在JavaScript的世界中,所有代码都是单线程执行的。自己不能创建一个分支
去执行其他代码. - js异步执行可以用回调函数实现,就是把请求交给别人(浏览器),自己不等待结果返回,只告诉他到时候某种情况下执行对应的回调函数.然后我还是继续往下执行.
- 浏览器那边,执行完了你扔给它的任务,再赛回js当前线程的task queue里排队.具体参考知乎回答,浏览器这种典型的GUI程序,应该有event-loop之类的东西吧,略过不细究.
- 为了代码复用,还有更好的写代码,比如说线性的一路写下去,而不是 闪转腾挪的定义回调函数,传入回调函数等等操作, 有了Promise对象.
- 比如写成这样
var ajax = ajaxGet('http://...');
ajax.ifSuccess(success)
.ifFail(fail);
这种链式写法的好处在于,先统一执行AJAX逻辑,不关心如何处理结果,然后,根据结果是成功还是失败,在将来的某个时候调用success函数或fail函数。
- Promise好处 执行代码和处理结果的代码清晰地分离了
个人理解: 先承诺,在实现具体执行的内容.
Promise().then().then....catch() 多任务串行执行.
情景化记忆:
在一个任务链中,比如我要向上级部门一层层的往上提交申请,if(某种条件)承诺帮你resolve解决问题,else承诺reject你的请求.
他给出的resolve问题的办法只是个空头Promise,then到总经理那实现具体承诺,如果总经理还是给一个空头承诺(返回Promise实例),还得then到董事长那里....
任一一步做出的是reject的承诺,还有什么好说的,被拒绝了,后面的就不会再往上走了呀.
准备catch 拒绝通知吧,另外有什么同步异常你也能cath到, 比如申请材料被领导的狗吃了...
var multiply = function (num) {
return new Promise(function (f1, f2) {
var result = num * num;
console.log(`calculating ${num} * ${num} = ${result}`);
var n = Math.random() * 2;
if (n < 1) {
setTimeout(f1, 1000, result);
} else {
setTimeout(f2, 1000, result); //不管哪一个then里调用,都会执行catch,像 catch异常一样
}
});
};
var add = function (num) {
return new Promise(function (f1, f2) {
var result = num + num;
console.log(`calculating ${num}+${num} = ${result}`);
setTimeout(f1, 1000, result);
});
};
var final = function (num) {
console.log("finally, the result is " + num + "!");
}
var p1 = new Promise(function (resolve, reject) {
console.log('start new Promise...');
resolve(4);
});
p1.then(multiply)
.then(add)
.then(add)
.then(multiply)
.then(add)
.then(multiply)
.then(final)
.catch(function (res) {
console.log('error: ', res);
}); // 串行执行
//任一个任务里调用f2/reject/第二个回调函数,将不再继续并执行错误处理函数catch。
Promise(function()) 里面函数传入的两个回调函数,第一个在接下来的then里去实现,第二个在catch里实现. (个人理解:实现)
先Promise,then实现具体执行的内容,如前面仍然开了空头支票(返回一个Promise),再接then里去实现. 先做任务1,在做任务2,在做任务3...,任何一步执行了参数二传入的回调函数,或者抛出了同步异常,则会中断任务链执行catch里的函数.
就像catch异常一样.
Promise.all([p1,p2,...]) 多任务并行执行.
都要成功才进入then,任一失败被catch
/// Promise.all()
var p3 = new Promise(function (resolve, reject) {
setTimeout(resolve, 500, 'P3');
});
var p4 = new Promise(function (resolve, reject) {
setTimeout(reject, 600, 'P4'); // 只要有一个任务失败就是失败
});
//同时执行p1和p2,并在它们都完成后执行then:
var res = Promise.all([p3, p4]).then(function (results) {
console.log("all result",results); // 获得一个Array: ['P1', 'P2']
}).catch(function(error){
console.log("all error:",error);
});
Promise.race([p1,p2,...]) 多任务赛跑
赛跑,谁先成功谁执行then,任一失败都被catch
注意:并不是指:只要一个成功,其它的失败了没关系,then()和catch(),谁先调用算谁的
var p5 = new Promise(function (resolve, reject) {
setTimeout(resolve, 500, 'P5');
});
var p6 = new Promise(function (resolve, reject) {
setTimeout(resolve, 600, 'P6');
});
// race 赛跑 ,将多个Promise实例,包装成一个Promise实例,这些Promise只要有一个率先状态改变,
Promise.race([p5, p6]).then(function (result) {
console.log("race result:", result);
}).catch(function(error){
console.log("race error:",error);
});
应用情景: 1. 多任务容错,取先完成的那个. 2.计时, 计时任务先执行catch()则超时了,其它任务也就中止了.