当前位置: 首页 > news >正文

网站建设好的公司前端做项目网站

网站建设好的公司,前端做项目网站,nginx php7 wordpress,爱站网主要功能Promise是前端面试中的高频问题#xff0c;如果你能根据PromiseA的规范#xff0c;写出符合规范的源码#xff0c;那么我想#xff0c;对于面试中的Promise相关的问题#xff0c;都能够给出比较完美的答案。 我的建议是#xff0c;对照规范多写几次实现#xff0c;也许…Promise是前端面试中的高频问题如果你能根据PromiseA的规范写出符合规范的源码那么我想对于面试中的Promise相关的问题都能够给出比较完美的答案。 我的建议是对照规范多写几次实现也许第一遍的时候是改了多次才能通过测试那么需要反复的写我已经将Promise的源码实现写了不下七遍不那么聪明的话当然需要更加努力啦~ Promise的源码实现 /*** 1. new Promise时需要传递一个 executor 执行器执行器立刻执行* 2. executor 接受两个参数分别是 resolve 和 reject* 3. promise 只能从 pending 到 rejected, 或者从 pending 到 fulfilled* 4. promise 的状态一旦确认就不会再改变* 5. promise 都有 then 方法then 接收两个参数分别是 promise 成功的回调 onFulfilled, * 和 promise 失败的回调 onRejected* 6. 如果调用 then 时promise已经成功则执行 onFulfilled并将promise的值作为参数传递进去。* 如果promise已经失败那么执行 onRejected, 并将 promise 失败的原因作为参数传递进去。* 如果promise的状态是pending需要将onFulfilled和onRejected函数存放起来等待状态确定后再依次将对应的函数执行(发布订阅)* 7. then 的参数 onFulfilled 和 onRejected 可以缺省* 8. promise 可以then多次promise 的then 方法返回一个 promise* 9. 如果 then 返回的是一个结果那么就会把这个结果作为参数传递给下一个then的成功的回调(onFulfilled)* 10. 如果 then 中抛出了异常那么就会把这个异常作为参数传递给下一个then的失败的回调(onRejected)* 11.如果 then 返回的是一个promise那么会等这个promise执行完promise如果成功* 就走下一个then的成功如果失败就走下一个then的失败*/const PENDING pending; const FULFILLED fulfilled; const REJECTED rejected; function Promise(executor) {let self this;self.status PENDING;self.onFulfilled [];//成功的回调self.onRejected []; //失败的回调//PromiseA 2.1function resolve(value) {if (self.status PENDING) {self.status FULFILLED;self.value value;self.onFulfilled.forEach(fn fn());//PromiseA 2.2.6.1}}function reject(reason) {if (self.status PENDING) {self.status REJECTED;self.reason reason;self.onRejected.forEach(fn fn());//PromiseA 2.2.6.2}}try {executor(resolve, reject);} catch (e) {reject(e);} }Promise.prototype.then function (onFulfilled, onRejected) {//PromiseA 2.2.1 / PromiseA 2.2.5 / PromiseA 2.2.7.3 / PromiseA 2.2.7.4onFulfilled typeof onFulfilled function ? onFulfilled : value value;onRejected typeof onRejected function ? onRejected : reason { throw reason };let self this;//PromiseA 2.2.7let promise2 new Promise((resolve, reject) {if (self.status FULFILLED) {//PromiseA 2.2.2//PromiseA 2.2.4 --- setTimeoutsetTimeout(() {try {//PromiseA 2.2.7.1let x onFulfilled(self.value);resolvePromise(promise2, x, resolve, reject);} catch (e) {//PromiseA 2.2.7.2reject(e);}});} else if (self.status REJECTED) {//PromiseA 2.2.3setTimeout(() {try {let x onRejected(self.reason);resolvePromise(promise2, x, resolve, reject);} catch (e) {reject(e);}});} else if (self.status PENDING) {self.onFulfilled.push(() {setTimeout(() {try {let x onFulfilled(self.value);resolvePromise(promise2, x, resolve, reject);} catch (e) {reject(e);}});});self.onRejected.push(() {setTimeout(() {try {let x onRejected(self.reason);resolvePromise(promise2, x, resolve, reject);} catch (e) {reject(e);}});});}});return promise2; }function resolvePromise(promise2, x, resolve, reject) {let self this;//PromiseA 2.3.1if (promise2 x) {reject(new TypeError(Chaining cycle));}if (x typeof x object || typeof x function) {let used; //PromiseA2.3.3.3.3 只能调用一次try {let then x.then;if (typeof then function) {//PromiseA2.3.3then.call(x, (y) {//PromiseA2.3.3.1if (used) return;used true;resolvePromise(promise2, y, resolve, reject);}, (r) {//PromiseA2.3.3.2if (used) return;used true;reject(r);});}else{//PromiseA2.3.3.4if (used) return;used true;resolve(x);}} catch (e) {//PromiseA 2.3.3.2if (used) return;used true;reject(e);}} else {//PromiseA 2.3.3.4resolve(x);} }module.exports Promise;有专门的测试脚本可以测试所编写的代码是否符合PromiseA的规范。 首先在promise实现的代码中增加以下代码: Promise.defer Promise.deferred function () {let dfd {};dfd.promise new Promise((resolve, reject) {dfd.resolve resolve;dfd.reject reject;});return dfd; }安装测试脚本: npm install -g promises-aplus-tests如果当前的promise源码的文件名为promise.js 那么在对应的目录执行以下命令: promises-aplus-tests promise.jspromises-aplus-tests中共有872条测试用例。以上代码可以完美通过所有用例。 对上面的代码实现做一点简要说明(其它一些内容注释中已经写得很清楚): onFulfilled 和 onFulfilled的调用需要放在setTimeout因为规范中表示: onFulfilled or onRejected must not be called until the execution context stack contains only platform code。使用setTimeout只是模拟异步原生Promise并非是这样实现的。在 resolvePromise 的函数中为何需要usedd这个flag,同样是因为规范中明确表示: If both resolvePromise and rejectPromise are called, or multiple calls to the same argument are made, the first call takes precedence, and any further calls are ignored. 因此我们需要这样的flag来确保只会执行一次。self.onFulfilled 和 self.onRejected 中存储了成功的回调和失败的回调根据规范2.6显示当promise从pending态改变的时候需要按照顺序去指定then对应的回调。 PromiseA的规范(翻译版) PS: 下面是我翻译的规范供参考 术语 promise 是一个有then方法的对象或者是函数行为遵循本规范thenable 是一个有then方法的对象或者是函数value 是promise状态成功时的值包括 undefined/thenable或者是 promiseexception 是一个使用throw抛出的异常值reason 是promise状态失败时的值 要求 2.1 Promise States Promise 必须处于以下三个状态之一: pending, fulfilled 或者是 rejected 2.1.1 如果promise在pending状态 2.1.1.1 可以变成 fulfilled 或者是 rejected2.1.2 如果promise在fulfilled状态 2.1.2.1 不会变成其它状态2.1.2.2 必须有一个value值2.1.3 如果promise在rejected状态 2.1.3.1 不会变成其它状态2.1.3.2 必须有一个promise被reject的reason概括即是:promise的状态只能从pending变成fulfilled或者从pending变成rejected.promise成功有成功的value.promise失败的话有失败的原因 2.2 then方法 promise必须提供一个then方法来访问最终的结果 promise的then方法接收两个参数 promise.then(onFulfilled, onRejected)2.2.1 onFulfilled 和 onRejected 都是可选参数 2.2.1.1 onFulfilled 必须是函数类型2.2.1.2 onRejected 必须是函数类型2.2.2 如果 onFulfilled 是函数: 2.2.2.1 必须在promise变成 fulfilled 时调用 onFulfilled参数是promise的value 2.2.2.2 在promise的状态不是 fulfilled 之前不能调用 2.2.2.3 onFulfilled 只能被调用一次2.2.3 如果 onRejected 是函数: 2.2.3.1 必须在promise变成 rejected 时调用 onRejected参数是promise的reason 2.2.3.2 在promise的状态不是 rejected 之前不能调用 2.2.3.3 onRejected 只能被调用一次2.2.4 onFulfilled 和 onRejected 应该是微任务 2.2.5 onFulfilled 和 onRejected 必须作为函数被调用 2.2.6 then方法可能被多次调用 2.2.6.1 如果promise变成了 fulfilled态所有的onFulfilled回调都需要按照then的顺序执行 2.2.6.2 如果promise变成了 rejected态所有的onRejected回调都需要按照then的顺序执行2.2.7 then必须返回一个promise promise2 promise1.then(onFulfilled, onRejected);2.2.7.1 onFulfilled 或 onRejected 执行的结果为x,调用 resolvePromise 2.2.7.2 如果 onFulfilled 或者 onRejected 执行时抛出异常e,promise2需要被reject 2.2.7.3 如果 onFulfilled 不是一个函数promise2 以promise1的值fulfilled 2.2.7.4 如果 onRejected 不是一个函数promise2 以promise1的reason rejected2.3 resolvePromise resolvePromise(promise2, x, resolve, reject) 2.3.1 如果 promise2 和 x 相等那么 reject promise with a TypeError 2.3.2 如果 x 是一个 promsie 2.3.2.1 如果x是pending态那么promise必须要在pending,直到 x 变成 fulfilled or rejected. 2.3.2.2 如果 x 被 fulfilled, fulfill promise with the same value. 2.3.2.3 如果 x 被 rejected, reject promise with the same reason.2.3.3 如果 x 是一个 object 或者 是一个 function 2.3.3.1 let then x.then. 2.3.3.2 如果 x.then 这步出错那么 reject promise with e as the reason.. 2.3.3.3 如果 then 是一个函数then.call(x, resolvePromiseFn, rejectPromise)2.3.3.3.1 resolvePromiseFn 的 入参是 y, 执行 resolvePromise(promise2, y, resolve, reject);2.3.3.3.2 rejectPromise 的 入参是 r, reject promise with r.2.3.3.3.3 如果 resolvePromise 和 rejectPromise 都调用了那么第一个调用优先后面的调用忽略。2.3.3.3.4 如果调用then抛出异常e 2.3.3.3.4.1 如果 resolvePromise 或 rejectPromise 已经被调用那么忽略2.3.3.3.4.3 否则reject promise with e as the reason 2.3.3.4 如果 then 不是一个function. fulfill promise with x.2.3.4 如果 x 不是一个 object 或者 functionfulfill promise with x. Promise的其他方法 虽然上述的promise源码已经符合PromiseA的规范但是原生的Promise还提供了一些其他方法如: Promise.resolve()Promise.reject()Promise.prototype.catch()Promise.prototype.finally()Promise.all()Promise.race() 下面具体说一下每个方法的实现: Promise.resolve Promise.resolve(value) 返回一个以给定值解析后的Promise 对象. 如果 value 是个 thenable 对象返回的promise会“跟随”这个thenable的对象采用它的最终状态如果传入的value本身就是promise对象那么Promise.resolve将不做任何修改、原封不动地返回这个promise对象。其他情况直接返回以该值为成功状态的promise对象。 Promise.resolve function (param) {if (param instanceof Promise) {return param;}return new Promise((resolve, reject) {if (param typeof param object typeof param.then function) {setTimeout(() {param.then(resolve, reject);});} else {resolve(param);}}); }thenable对象的执行加 setTimeout的原因是根据原生Promise对象执行的结果推断的如下的测试代码原生的执行结果为: 20 400 30;为了同样的执行顺序增加了setTimeout延时。 测试代码: let p Promise.resolve(20); p.then((data) {console.log(data); });let p2 Promise.resolve({then: function(resolve, reject) {resolve(30);} });p2.then((data) {console.log(data) });let p3 Promise.resolve(new Promise((resolve, reject) {resolve(400) })); p3.then((data) {console.log(data) });Promise.reject Promise.reject方法和Promise.resolve不同Promise.reject()方法的参数会原封不动地作为reject的理由变成后续方法的参数。 Promise.reject function (reason) {return new Promise((resolve, reject) {reject(reason);}); }Promise.prototype.catch Promise.prototype.catch 用于指定出错时的回调是特殊的then方法catch之后可以继续 .then Promise.prototype.catch function (onRejected) {return this.then(null, onRejected); }Promise.prototype.finally 不管成功还是失败都会走到finally中,并且finally之后还可以继续then。并且会将值原封不动的传递给后面的then. Promise.prototype.finally function (callback) {return this.then((value) {return Promise.resolve(callback()).then(() {return value;});}, (err) {return Promise.resolve(callback()).then(() {throw err;});}); }Promise.all Promise.all(promises) 返回一个promise对象 如果传入的参数是一个空的可迭代对象那么此promise对象回调完成(resolve),只有此情况是同步执行的其它都是异步返回的。如果传入的参数不包含任何 promise则返回一个异步完成.promises 中所有的promise都promise都“完成”时或参数中不包含 promise 时回调完成。如果参数中有一个promise失败那么Promise.all返回的promise对象失败在任何情况下Promise.all 返回的 promise 的完成状态的结果都是一个数组 Promise.all function (promises) {promises Array.from(promises);//将可迭代对象转换为数组return new Promise((resolve, reject) {let index 0;let result [];if (promises.length 0) {resolve(result);} else {function processValue(i, data) {result[i] data;if (index promises.length) {resolve(result);}}for (let i 0; i promises.length; i) {//promises[i] 可能是普通值Promise.resolve(promises[i]).then((data) {processValue(i, data);}, (err) {reject(err);return;});}}}); }测试代码: var promise1 new Promise((resolve, reject) {resolve(3); }) var promise2 42; var promise3 new Promise(function(resolve, reject) {setTimeout(resolve, 100, foo); });Promise.all([promise1, promise2, promise3]).then(function(values) {console.log(values); //[3, 42, foo] },(err){console.log(err) });var p Promise.all([]); // will be immediately resolved var p2 Promise.all([1337, hi]); // non-promise values will be ignored, but the evaluation will be done asynchronously console.log(p); console.log(p2) setTimeout(function(){console.log(the stack is now empty);console.log(p2); });Promise.race Promise.race函数返回一个 Promise它将与第一个传递的 promise 相同的完成方式被完成。它可以是完成 resolves也可以是失败rejects这要取决于第一个完成的方式是两个中的哪个。 如果传的参数数组是空则返回的 promise 将永远等待。 如果迭代包含一个或多个非承诺值和/或已解决/拒绝的承诺则 Promise.race 将解析为迭代中找到的第一个值。 Promise.race function (promises) {promises Array.from(promises);//将可迭代对象转换为数组return new Promise((resolve, reject) {if (promises.length 0) {return;} else {for (let i 0; i promises.length; i) {Promise.resolve(promises[i]).then((data) {resolve(data);return;}, (err) {reject(err);return;});}}}); }测试代码: Promise.race([new Promise((resolve, reject) { setTimeout(() { resolve(100) }, 1000) }),undefined,new Promise((resolve, reject) { setTimeout(() { reject(100) }, 100) }) ]).then((data) {console.log(success , data); }, (err) {console.log(err ,err); });Promise.race([new Promise((resolve, reject) { setTimeout(() { resolve(100) }, 1000) }),new Promise((resolve, reject) { setTimeout(() { resolve(200) }, 200) }),new Promise((resolve, reject) { setTimeout(() { reject(100) }, 100) }) ]).then((data) {console.log(data); }, (err) {console.log(err); });
http://www.w-s-a.com/news/179089/

相关文章:

  • 网站设计常见问题建设工程网上质检备案网站
  • 网站怎样优化文章关键词建设网站需要钱吗
  • 加强网站建设和管理的通知重庆网站推广产品
  • 网站建设术语解释百度发布信息的免费平台
  • 情公司做的网站seo与网站优化 pdf
  • 做一个购物网站多少钱江阴市住房和城乡建设局网站
  • 网站建设都包括哪些ps怎么做网站首页和超链接
  • 怎样低成本做网站推广编辑网站教程
  • 邯郸网站建设信息网站开发报价人天
  • 王店镇建设中心小学网站酷玛网站建设
  • 网站需求方案wordpress博客主题推荐
  • 网站安全证书过期怎么办那个视频网站最好最全网址
  • 外贸上哪个网站开发客户建行个人网上银行登录入口
  • 空间除了可以做网站还能干什么qq钓鱼网站
  • 网站 技术企业网站用免费程序
  • 做网站的中文名字汕尾网站开发
  • 网站推广效果推广网站推荐
  • 腾讯企业网站建设网络推广比较经典和常用的方法有
  • 四川成都网站网页设计上海外贸网站制作公司
  • wordpress模板首页图片锦州网站做优化
  • 哔哩哔哩网站建设分析有哪些做网站好的公司
  • 福建建设执业中心网站沧州网络推广外包公司
  • 做网站怎么改关键词营销网站建设818gx
  • 广撒网网站怎么进行网络营销
  • 中职计算机网站建设教学计划电商网站如何避免客户信息泄露
  • 惠州微网站建设外贸进出口代理公司
  • 网站建设最常见的问题建设银行网站机构
  • 网站集群建设相关的招标南通seo网站建设费用
  • 网络培训的网站建设能够做二维码网站
  • 网站类游戏网站开发wordpress 文章首标点