网站制作流程和方法,上海企业服务,网文推广怎么做,wordpress qq 微博1. Promise简介 promise是异步编程的一种解决方案#xff0c;它出现的初衷是为了解决回调地狱的问题。 打个比方#xff0c;我需要#xff1a; --(延迟1s)-- 输出1 --(延迟2s)-- 输出2 --(延迟3s)-- 输出3 通常写法#xff1a; setTimeout(() {console.log… 1. Promise简介 promise是异步编程的一种解决方案它出现的初衷是为了解决回调地狱的问题。 打个比方我需要 --(延迟1s)-- 输出1 --(延迟2s)-- 输出2 --(延迟3s)-- 输出3 通常写法 setTimeout(() {console.log(1);setTimeout(() {console.log(2);setTimeout(() {console.log(3); }, 3000)}, 2000)
}, 1000) 这样的多重的嵌套的回调被称为回调地狱这样的代码可读性很差不利于理解。 如果用promise的话画风一转 function delay(time, num) {return new Promise((res, rej) {setTimeout(() {console.log(num);res();}, time*1000)});
}
delay(1, 1).then(() {return delay(2, 2);
}).then(() {delay(3, 3);
}) 使用了promise的链式调用代码结构更清晰。 是不是很棒那还不赶快get起来~ 2. Promise的使用 调用方式如下 new Promise((resolve, reject) {if(some option) {resolve(some value);} else {reject(some error);}
}).then(val {// ...},error {// ...}
) Promise构造函数接收一个函数型参数fnfn有两个参数分别是resolve、rejectPromise还有一个Promise.prototype.then方法该方法接收两个参数分别是成功的回调函数succ和失败的回调函数error。 在fn中调用resolve会触发then中的succ回调调用reject会触发error回调。 2.1 参数传递 在fn内部调用resolve/reject传入的参数会作为相应参数传入相应的回调函数 new Promise((res, rej) {res(happy)
}).then(val {console.log(val); // happy
});new Promise((res, rej) {rej(error!);
}).then(val {}, err {console.log(err); // error!
}); 链式调用时若上一级没有传递值则默认为undefined new Promise((res, rej) {res(a);
}).then(val {return b
}).then(val {console.log(val); // b
}).then((val) {console.log(val); // undefined
}); 若上一级的then中传递的并非函数则忽略该级 new Promise((res, rej) {res(a);
}).then(val {return b;
}).then(val {console.log(val); // breturn c;
}).then({ // 并非函数name: lan
}).then((val) {console.log(val); // c
}); 2.2 参数传递例题 let doSomething function() {return new Promise((resolve, reject) {resolve(返回值);});
};let doSomethingElse function() {return 新的值;
}doSomething().then(function () {return doSomethingElse();
}).then(resp {console.warn(resp);console.warn(1 );
});doSomething().then(function () {doSomethingElse();
}).then(resp {console.warn(resp);console.warn(2 );
});doSomething().then(doSomethingElse()).then(resp {console.warn(resp);console.warn(3 );
});doSomething().then(doSomethingElse).then(resp {console.warn(resp);console.warn(4 );
}); 结合上面的讲解想一想会输出什么答案及解析 3. Promise.prototype.then 当Promise中的状态(pending --- resolved or rejected)发生变化时才会执行then方法。 调用then返回的依旧是一个Promise实例 ( 所以才可以链式调用... ) new Promise((res, rej) {res(a);
}).then(val {return b;
});// 等同于
new Promise((res, rej) {res(a);
}).then(val {return new Promise((res, rej) {res(b);});
}); then中的回调总会异步执行 new Promise((res, rej) {console.log(a);res();
}).then(() {console.log(b);
});
console.log(c);
// a c b 如果你不在Promise的参数函数中调用resolve或者reject那么then方法永远不会被触发 new Promise((res, rej) {console.log(a);
}).then(() {console.log(b);
});
console.log(c);
// a c 4. Promise的静态方法 Promise还有四个静态方法分别是resolve、reject、all、race下面我们一一介绍一下。 4.1 Promise.resolve() 除了通过new Promise()的方式我们还有两种创建Promise对象的方法Promise.resolve()相当于创建了一个立即resolve的对象。如下两段代码作用相同 Promise.resolve(a);new Promise((res, rej) {res(a);
}); 当然根据传入的参数不同Promise.resolve()也会做出不同的操作。 参数是一个 Promise 实例如果参数是 Promise 实例那么Promise.resolve将不做任何修改、原封不动地返回这个实例。 参数是一个thenable对象thenable对象指的是具有then方法的对象比如下面这个对象。 let thenable {then: function(resolve, reject) {resolve(42);}
}; Promise.resolve方法会将这个对象转为 Promise对象然后就立即执行thenable对象的then方法。 参数不是具有then方法的对象或根本就不是对象如果参数是一个原始值或者是一个不具有then方法的对象则Promise.resolve方法返回一个新的 Promise 对象状态为resolved。 不带有任何参数Promise.resolve方法允许调用时不带参数直接返回一个resolved状态的 Promise 对象。 值得注意的一点是该静态方法是在本次事件轮询结束前调用而不是在下一次事件轮询开始时调用。关于事件轮询可以看这里——JavaScript 运行机制详解再谈Event Loop 4.2 Promise.reject() 和Promise.resolve()类似只不过一个是触发成功的回调一个是触发失败的回调 4.3 Promise.all() Promise的all方法提供了并行执行异步操作的能力并且在所有异步操作执行完后才执行回调。 function asyncFun1() {return new Promise((res, rej) {setTimeout(() { res(a);}, 1000);});
}
function asyncFun2() {return new Promise((res, rej) {setTimeout(() { res(b);}, 1000);});
}
function asyncFun3() {return new Promise((res, rej) {setTimeout(() { res(c);}, 1000);});
}
Promise.all([asyncFun1(), asyncFun2(), asyncFun3()]).then((val) {console.log(val);
});
Promise.all([asyncFun1(), asyncFun2(), asyncFun3()]).then((val) {console.log(val); // [a, b, c]
}); 用Promise.all来执行all接收一个数组参数里面的值最终都算返回Promise对象。这样三个异步操作的并行执行的等到它们都执行完后才会进到then里面。有了all你就可以并行执行多个异步操作并且在一个回调中处理所有的返回数据。 适用场景打开网页时预先加载需要用到的各种资源如图片、flash以及各种静态文件。所有的都加载完后我们再进行页面的初始化。 4.4 Promise.race() race()和all相反all()是数组中所有Promise都执行完毕就执行then而race()是一旦有一个Promise执行完毕就会执行then()用上面的三个Promise返回值函数举例 Promise.race([asyncFun1(), asyncFun2(), asyncFun3()]).then((val) {console.log(val); // a
}); 5. 链式调用经典例题 看了这么多关于Promise的知识我们来做一道题巩固一下。 写一个类Man实现以下链式调用调用方式
new Man(lan).sleep(3).eat(apple).sleep(5).eat(banana);
打印
hello, lan -(等待3s)-- lan eat apple -(等待5s)-- lan eat banana 思路 在原型方法中返回this达到链式调用的目的等待3s执行的效果可以用Promise then实现具体实现如下 class Man {constructor(name) {this.name name;this.sayName();this.rope Promise.resolve(); // 定义全局Promise作链式调用}sayName() {console.log(hello, ${this.name});}sleep(time) {this.rope this.rope.then(() {return new Promise((res, rej) {setTimeout(() {res();}, time*1000);});});return this;}eat(food) {this.rope this.rope.then(() {console.log(${this.name} eat ${food}); });return this;}
}new Man(lan).sleep(3).eat(apple).sleep(5).eat(banana); ok不知道你有没有看懂呢如果能完全理解代码那你的Promise可以通关了顺便来个小思考,下面这种写法可以吗和上面相比有什么区别 class Man1345 {constructor(name) {this.name name;this.sayName(); }sayName() {console.log(hello, ${this.name});}sleep(time) { this.rope new Promise((res, rej) {setTimeout(() {res();}, time*1000);}); return this;}eat(food) {this.rope this.rope.then(() { console.log(${this.name} eat ${food}); });return this;}
}new Man(lan).sleep(3).eat(apple).sleep(5).eat(banana); 简单的说第二段代码的执行结果是 hello, lan -(等待3s)-- lan eat apple --- lan eat banana 为什么会出现这种差别 因为第二段代码每一次调用sleep都会new一个新的Promise对象调用了两次sleep就new了两个Promise对象。这两个对象是异步并行执行会造成两句eat同时显示。 和以下情况类似 var time1 setTimeout(() {console.log(a);
}, 1000)
var time2 setTimeout(() {console.log(b);
}, 1000)
// 同时输出 a b 抽象一点的讲解是 // 第一段正确的代码的执行为
var p1 new Promise().then(停顿3s).then(打印食物).then(停顿5s).then(打印食物);// 第二段代码的执行行为p1、p2异步并行执行
var p1 new Promise().then(停顿3s).then(打印食物);
var p2 new Promise().then(停顿5s).then(打印食物);
总结 Promise的经常用到的地方 摆脱回调地狱多个异步任务同步Promise是我们的好帮手不过还有另一种方法也可以做到那就是asyncawait可以多多了解一下。 参考资料 ECMAScript 6 入门 通俗浅显的理解Promise中的then 大白话讲解promise 转载于:https://www.cnblogs.com/wind-lanyan/p/8849643.html