摘要:答案題目三解析方法的參數如果是一個原始值,或者是一個不具有方法的對象,則方法返回一個新的對象,狀態(tài)為,方法的參數,會同時傳給回調函數。
常見Promise面試題 題目一
const promise = new Promise((resolve, reject) => { console.log(1); resolve(); console.log(2); }) promise.then(() => { console.log(3); }) console.log(4);
解析
首先Promise新建后立即執(zhí)行,所以會先輸出1,2,而Promise.then()內部的代碼在當次事件循環(huán)的結尾立即執(zhí)行,所以會先輸出4,最后輸出3.
答案:1 2 4 3
const promise = new Promise((resolve, reject) => { resolve("success1"); reject("error"); resolve("success2"); }); promise.then((res) => { console.log("then:", res); }).catch((err) => { console.log("catch:", err); })
解析
resolve函數Promise對象的狀態(tài)從“未完成”變?yōu)椤俺晒Α保磸膒ending變?yōu)閞esolved),在異步操作成功時調用,并將異步操作的結果,作為參數傳遞出去;
reject函數將Promise對象的狀態(tài)從“未完成”變?yōu)椤笆 保磸膒ending變?yōu)閞ejected),在異步操作失敗時調用,并將異步操作報出的錯誤,作為參數傳遞出去。
而一旦狀態(tài)改變,就不會有再變。
所以代碼中的reject("error");不會有作用。
Promise只能resolve一次,剩下的調用都會被忽略。
所以第二次resolve("success");也不會有作用。
答案:then:success1
Promise.resolve(1) .then(2) .then(Promise.resolve(3)) .then(console.log)
解析
Promise.resolve方法的參數如果是一個原始值,或者是一個不具有then方法的對象,則Promise.resolve方法返回一個新的Promise對象,狀態(tài)為resolved,Promise.resolve方法的參數,會同時傳給回調函數。
then方法接受的參數是函數,而如果傳遞的并非是一個函數,它實際上會將其解釋為then(null),這就會導致前一個Promise的結果會傳遞下面。
答案 1
紅燈3秒亮一次,綠燈1秒亮一次,黃燈2秒亮一次;如何讓三個燈不斷交替重復亮燈?(用Promise實現)三個亮燈函數已經存在:
function red() { console.log("red"); } function green() { console.log("green"); } function yellow() { console.log("yellow"); }
解析
紅燈3秒亮一次,綠燈1秒亮一次 ,黃燈2秒亮一次,意思就是3秒執(zhí)行一次red函數,2秒執(zhí)行一次green函數,1秒執(zhí)行一次yellow函數,不斷交替重復亮燈,意思就是按照這個順序一直執(zhí)行這3個函數,這步可以利用遞歸來實現。
答案:
function red() { console.log("red"); } function green() { console.log("green"); } function yellow() { console.log("yellow"); } var light = function (timmer, cb) { return new Promise(function (resolve, reject) { setTimeout(function () { cb(); resolve(); }, timmer); }); }; var step = function () { Promise.resolve().then(function () { return light(3000, red); }).then(function () { return light(2000, green); }).then(function () { return light(1000, yellow); }).then(function () { step(); }); } step();題目五
實現mergePromise函數,把傳進去的數組按順序先后執(zhí)行,并且把返回的數據先后放到數組data中。
const timeout = ms => new Promise((resolve, reject) => { setTimeout(() => { resolve(); }, ms); }); const ajax1 = () => timeout(2000).then(() => { console.log("1"); return 1; }); const ajax2 = () => timeout(1000).then(() => { console.log("2"); return 2; }); const ajax3 = () => timeout(2000).then(() => { console.log("3"); return 3; }); const mergePromise = ajaxArray => { // 在這里實現你的代碼 }; mergePromise([ajax1, ajax2, ajax3]).then(data => { console.log("done"); console.log(data); // data 為 [1, 2, 3] }); // 要求分別輸出 // 1 // 2 // 3 // done // [1, 2, 3]
解析
首先ajax1,ajax2,ajax3都是函數,只是這些函數執(zhí)行后會返回一個Promise,按照題目要求只要順序執(zhí)行這三個函數就好了,然后把結果放到data中,但是這些函數都是異步操作,想要按順序執(zhí)行輸出1,2,3并非那么容易,舉例
function A() { setTimeout(function () { console.log("a"); }, 3000); } function B() { setTimeout(function () { console.log("b"); }, 1000); } A(); B(); // b // a
例子中按照順序執(zhí)行A,B但是輸出的結果卻是b,a。因為對于異步函數來說,并不會按順序執(zhí)行完一個,再執(zhí)行后一個。
這道題主要考察用Promise控制異步流程,讓這些涵涵素,一個執(zhí)行完,再執(zhí)行下一個。
答案
// 保存數組中的函數執(zhí)行后的結果 var data = []; // Promise.resolve方法調用時不帶參數,直接返回一個resolved狀態(tài)的 Promise 對象。 var sequence = Promise.resolve(); ajaxArray.forEach(function (item) { // 第一次的 then 方法用來執(zhí)行數組中的每個函數, // 第二次的 then 方法接受數組中的函數執(zhí)行后返回的結果, // 并把結果添加到 data 中,然后把 data 返回。 sequence = sequence.then(item).then(function (res) { data.push(res); return data; }); }) // 遍歷結束后,返回一個 Promise,也就是 sequence, 他的 [[PromiseValue]] 值就是 data, // 而 data(保存數組中的函數執(zhí)行后的結果) 也會作為參數,傳入下次調用的 then 方法中。 return sequence;題目六
以下代碼最后輸出什么
const first = () => (new Promise((resolve, reject) => { console.log(3); let p = new Promise((resolve, reject) => { console.log(7); setTimeout(() => { console.log(5); resolve(6); }, 0) resolve(1); }); resolve(2); p.then((arg) => { console.log(arg); }); })); first().then((arg) => { console.log(arg); }); console.log(4);
解析
這道題主要理解js執(zhí)行機制
第一輪事件循環(huán)
先執(zhí)行宏任務,主script,new Promise立即執(zhí)行,輸出 3,
執(zhí)行p這個new Promise操作,輸出 7,
發(fā)現setTimeout,將回調函數放入下一輪任務隊列(Event Quene),p的then,暫且命名為then1,放入微任務隊列,且first也有then,命名為then2,放入微任務隊列。執(zhí)行console.log(4),輸出 4,宏任務執(zhí)行結束。
再執(zhí)行微任務,執(zhí)行then1,輸出 1,
執(zhí)行then2,輸出 3.
第一輪事件循環(huán)結束,開始執(zhí)行第二輪。
第二輪事件循環(huán)
先執(zhí)行宏任務里面的,也就是setTimeout的回調,輸出 5.
resolve(6)不會生效,因為p的Promise狀態(tài)一旦改變就不會再變化了。
答案 3 7 4 1 2 5
有8個圖片資源的url,已經存儲在數組urls中(即urls=["http://example.com/1.jpg",...,"http:""example.com/8.jpg"]),而且已經有一個函數function loading,輸入一個url鏈接,返回一個Promise,該Promise在圖片下載完成的時候resolve,下載失敗則reject。
但有一個要求,任何時刻同時下載的鏈接數量不可以超過3個。
請寫一段代碼實現這個需求,要求盡可能快速地將所有圖片下載完成。
var urls = ["https://www.kkkk1000.com/images/getImgData/getImgDatadata.jpg", "https://www.kkkk1000.com/images/getImgData/gray.gif", "https://www.kkkk1000.com/images/getImgData/Particle.gif", "https://www.kkkk1000.com/images/getImgData/arithmetic.png", "https://www.kkkk1000.com/images/getImgData/arithmetic2.gif", "https://www.kkkk1000.com/images/getImgData/getImgDataError.jpg", "https://www.kkkk1000.com/images/getImgData/arithmetic.gif", "https://www.kkkk1000.com/images/wxQrCode2.png"]; function loadImg(url) { return new Promise((resolve, reject) => { const img = new Image() img.onload = function () { console.log("一張圖片加載完成"); resolve(); } img.onerror = reject img.src = url }) };
解析
題目的意思是需要先并發(fā)請求3張圖片,當一張圖片加載完成后,又會繼續(xù)發(fā)起一張圖片的請求,讓并發(fā)數保持在3個,直到需要加載的圖片都全部發(fā)起請求。
用Promise來實現就是,先并發(fā)請求3個圖片資源,這樣可以得到3個Promise,組成一個數組promises,然后不斷調用Promise.race來返回最快改變狀態(tài)的Promise,然后從數組promises中刪掉這個Promise對象,再加入一個新的Promise,直到全部的url被取完,最后再使用Promise.all來處理一遍數組promises中沒有改變狀態(tài)的Promise
答案
var urls = ["https://www.kkkk1000.com/images/getImgData/getImgDatadata.jpg", "https://www.kkkk1000.com/images/getImgData/gray.gif", "https://www.kkkk1000.com/images/getImgData/Particle.gif", "https://www.kkkk1000.com/images/getImgData/arithmetic.png", "https://www.kkkk1000.com/images/getImgData/arithmetic2.gif", "https://www.kkkk1000.com/images/getImgData/getImgDataError.jpg", "https://www.kkkk1000.com/images/getImgData/arithmetic.gif", "https://www.kkkk1000.com/images/wxQrCode2.png"]; function loadImg(url) { return new Promise((resolve, reject) => { const img = new Image() img.onload = function () { console.log("一張圖片加載完成"); resolve(); } img.onerror = reject img.src = url }) }; function limitLoad(urls, handler, limit) { // 對數組做一個拷貝 const sequence = [].concat(urls) let promises = []; //并發(fā)請求到最大數 promises = sequence.splice(0, limit).map((url, index) => { // 這里返回的 index 是任務在 promises 的腳標,用于在 Promise.race 之后找到完成的任務腳標 return handler(url).then(() => { return index }); }); // 利用數組的 reduce 方法來以隊列的形式執(zhí)行 return sequence.reduce((last, url, currentIndex) => { return last.then(() => { // 返回最快改變狀態(tài)的 Promise return Promise.race(promises) }).catch(err => { // 這里的 catch 不僅用來捕獲 前面 then 方法拋出的錯誤 // 更重要的是防止中斷整個鏈式調用 console.error(err) }).then((res) => { // 用新的 Promise 替換掉最快改變狀態(tài)的 Promise promises[res] = handler(sequence[currentIndex]).then(() => { return res }); }) }, Promise.resolve()).then(() => { return Promise.all(promises) }) } limitLoad(urls, loadImg, 3) /* 因為 limitLoad 函數也返回一個 Promise,所以當 所有圖片加載完成后,可以繼續(xù)鏈式調用 limitLoad(urls, loadImg, 3).then(() => { console.log("所有圖片加載完成"); }).catch(err => { console.error(err); }) */題目八
封裝一個異步加載圖片的方法
function loadImageAsync(url) { return new Promise(function(resolve,reject) { var image = new Image(); image.onload = function() { resolve(image) }; image.onerror = function() { reject(new Error("Could not load image at" + url)); }; image.src = url; }); }
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規(guī)行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/101105.html
摘要:前文該系列下的前幾篇文章分別對不同的幾種異步方案原理進行解析,本文將介紹一些實際場景和一些常見的面試題。流程調度里比較常見的一種錯誤是看似串行的寫法,可以感受一下這個例子判斷以下幾種寫法的輸出結果辨別輸出順序這類題目一般出現在面試題里。 前文 該系列下的前幾篇文章分別對不同的幾種異步方案原理進行解析,本文將介紹一些實際場景和一些常見的面試題。(積累不太夠,后面想到再補) 正文 流程調度...
摘要:不過幸運的是所有面試的公司都給了,在這里總結下經驗吧。這里推薦下我當時看的一篇的面經,木易楊老師寫的大廠高級前端面試題匯總。 前言 本人畢業(yè)一年,最近陸續(xù)面試了頭條、瓜子、360、猿輔導、中信銀行、老虎等公司,由于最近比較寒冬而且招1-3年的并不多,再加上自己對公司規(guī)模和位置有一定要求,所以最后合適的也就這幾家了。不過幸運的是所有面試的公司都給了offer,在這里總結下經驗吧。掘金:h...
摘要:并總結經典面試題集各種算法和插件前端視頻源碼資源于一身的文檔,優(yōu)化項目,在瀏覽器端的層面上提升速度,幫助初中級前端工程師快速搭建項目。 本文是關注微信小程序的開發(fā)和面試問題,由基礎到困難循序漸進,適合面試和開發(fā)小程序。并總結vue React html css js 經典面試題 集各種算法和插件、前端視頻源碼資源于一身的文檔,優(yōu)化項目,在瀏覽器端的層面上提升速度,幫助初中級前端工程師快...
閱讀 3136·2021-11-11 16:54
閱讀 2291·2021-09-04 16:48
閱讀 3219·2019-08-29 16:08
閱讀 642·2019-08-29 15:13
閱讀 1344·2019-08-29 15:09
閱讀 2660·2019-08-29 12:45
閱讀 1926·2019-08-29 12:12
閱讀 444·2019-08-26 18:27