最近,我的好朋友正在換工作,在網(wǎng)上收到了很多offer。
其中之一就有來(lái)自一家名為 TikTok 公司的Offer,你可能非常熟悉該公司,也有可能不是很熟悉它。
朋友在面試的時(shí)候,他們讓我的朋友當(dāng)場(chǎng)寫(xiě)代碼來(lái)實(shí)現(xiàn)4個(gè)復(fù)雜方法的功能。
Promise.all() 方法將可迭代的 Promise 作為輸入,并返回單個(gè) Promise,該 Promise 解析為輸入 Promise 結(jié)果的數(shù)組。
當(dāng)所有輸入的 Promise 都已解決,或者輸入的可迭代對(duì)象不包含 Promise 時(shí),返回的 Promise 將得到解決。
它會(huì)在任何輸入Promise拒絕或非承諾拋出錯(cuò)誤時(shí)立即拒絕,并將拒絕第一個(gè)拒絕消息/錯(cuò)誤。
const promise1 = Promise.resolve(3);const promise2 = 42;const promise3 = new Promise((resolve, reject) => { setTimeout(resolve, 100, 'foo');});Promise.all([promise1, promise2, promise3]).then((values) => { console.log(values);});// expected output: Array [3, 42, "foo"]
現(xiàn)在,自己實(shí)現(xiàn)了一個(gè)
Promise.myAll = (promises) => { return new Promise((rs, rj) => { // counter let count = 0 // Storage results let result = [] const len = promises.length if (len === 0) { return rs([]) } promises.forEach((p, i) => { // Some array items may not be Promise and need to be converted manually Promise.resolve(p).then((res) => { count += 1 // Collect the return value of each Promise result[ i ] = res // Set the value of Promise to result, when all Promises are successful if (count === len) { rs(result) } // As long as one promise fails, the result is failure }).catch(rj) }) })}
進(jìn)行測(cè)試如下:
const p1 = Promise.resolve(1)const p2 = new Promise((resolve) => { setTimeout(() => resolve(2), 1000)})const p3 = new Promise((resolve) => { setTimeout(() => resolve(3), 3000)})const p4 = Promise.reject('err4')const p5 = Promise.reject('err5')// 1. All promise succeededconst p11 = Promise.myAll([ p1, p2, p3 ]) .then(console.log) // [ 1, 2, 3 ] .catch(console.log)// 2. One promise failedconst p12 = Promise.myAll([ p1, p2, p4 ]) .then(console.log) .catch(console.log) // err4// 3. Two promises failed. The final output is err4. The return value of the first failureconst p13 = Promise.myAll([ p1, p4, p5 ]) .then(console.log) .catch(console.log) // err4
localstorage不會(huì)像cookie一樣自動(dòng)過(guò)期,所以過(guò)期時(shí)間需要自己維護(hù)。
我的思路是:
使用setItem時(shí),保存過(guò)期時(shí)間。使用getItem時(shí),將時(shí)間與當(dāng)前時(shí)間進(jìn)行比較,如果大于當(dāng)前時(shí)間,則返回該值,否則,需要通過(guò)removeItem移除該值,并返回null。
const storage = { prefix: 'fatFish', timeSign: '|fatFish|', setItem (key, value, time) { // Protect the key from being overwritten key = `${this.prefix}${key}` // There is no incoming time, the default expiration time is one month, of course, it can be other times or not set time = time ? new Date(time).getTime() : Date.now() + 24 * 60 * 60 * 31 * 1000 // Constructs a string of the form 1646094676134|fatFish|"Front-end Fat Fish" window.localStorage.setItem(key, `${time}${this.timeSign}${JSON.stringify(value)}`) }, getItem (key) { key = `${this.prefix}${key}` let value = window.localStorage.getItem(key) if (value) { let index = value.indexOf(this.timeSign) let time = +value.slice(0, index) // Determine if time has expired if (time > Date.now()) { value = JSON.parse(value.slice(index + this.timeSign.length)) } else { value = null window.localStorage.removeItem(key) } } return value }}
現(xiàn)在,進(jìn)行測(cè)試
storage.setItem('name', 'front-end-fat-head', Date.now() + 100 * 1000) // fatFishname 1646095230191|fatFish|"front-end-fat-head"storage.getItem('name') // front-end-fat-head// 100s laterstorage.getItem('name') // nullstorage.setItem('obj', { name: 'front-end-fat-head', age: 100 }, Date.now() + 100 * 1000) // fatFishobj 1646095311366|fatFish|{"name":"front-end-fat-head","age":100}storage.getItem('obj') // {name: 'front-end-fat-head', age: 100}
基本上符合題主的要求。當(dāng)然,我們也可以處理異常情況,比如空間已滿、設(shè)置錯(cuò)誤等。
介紹:
oNode1 和 oNode2 位于同一文檔中,并且不會(huì)是同一節(jié)點(diǎn)。
function findCommonParent(oNode1, oNode2) { // fill here}
相信看到這道題你一定會(huì)用遞歸,但是沒(méi)有明確的思路。
這個(gè)時(shí)候不要緊張。從問(wèn)題中找出更有效的信息,盡量用更多的筆來(lái)畫(huà)(如果是現(xiàn)場(chǎng)面試,記得只帶一支鉛筆,有時(shí)候畫(huà)多了想法就出來(lái)了)。
讓我們嘗試畫(huà)出這兩個(gè)節(jié)點(diǎn)之間可能的關(guān)系。如下圖所示,它們的直接父節(jié)點(diǎn)就是答案。
oNode1 是目標(biāo)節(jié)點(diǎn)。當(dāng)然,反過(guò)來(lái)也是一樣的。oNode2 也可以是 oNode1 的祖先。
如下圖所示,兩個(gè)節(jié)點(diǎn)之間的距離很遠(yuǎn),看似沒(méi)有任何關(guān)系,但從其中任意一個(gè)向上查找,肯定能找到包含oNode1或oNode2的點(diǎn)。
根據(jù)上面的分析,相信你很快就能寫(xiě)出下面的代碼。
function findCommonParent(oNode1, oNode2) { // Cases 1 and 2 if (oNode1.contains(oNode2)) { return oNode1 // Cases 1 and 2 } else if (oNode2.contains(oNode1)) { return oNode2 } else { // Case 3, if you look up one of the nodes, you will find a common ancestor node return findCommonParent(oNode1.parentNode, oNode2) }}
遞歸很好理解,僅僅通過(guò)遍歷就可以實(shí)現(xiàn)嗎?事實(shí)上,遞歸問(wèn)題往往可以通過(guò)遍歷來(lái)解決。
function findCommonParent (oNode1, oNode2) { // Using oNode2 here is the same // If a node contains another node, return directly, otherwise keep looking up while (!oNode1.contains(oNode2)) { oNode1 = oNode1.parentNode } return oNode1}
這個(gè)問(wèn)題會(huì)比較簡(jiǎn)單,我們直接寫(xiě)代碼吧。
Input: [1, 2, 3]Output: [2, 4, 6]
Array.prototype.map2 = function (callback, ctx = null) { if (typeof callback !== 'function') { throw('callback must be a function') } return this.reduce((result, cur, index, array) => { return result.concat(callback.call(ctx, cur, index, array)) }, [])}let arr = [ 1, 2 ]let arr2 = arr.map2(function (it, i, array) { console.log(it, i, array, this) return it * 2}, { name: 'fatfish' })console.log(arr2)
看到這里,我想你已經(jīng)明白了,如果還不明白的話,那就是我還沒(méi)有說(shuō)清楚,下次,我爭(zhēng)取說(shuō)的更加清楚一些。當(dāng)然,如果你覺(jué)得這個(gè)內(nèi)容對(duì)你有幫助的話,請(qǐng)記得點(diǎn)贊我,關(guān)注我,以便學(xué)習(xí)能夠內(nèi)容,同時(shí),也不會(huì)錯(cuò)過(guò)我們的優(yōu)質(zhì)內(nèi)容。
本文鏈接:http://www.www897cc.com/showinfo-26-55057-0.htmlTikTok 面試:四個(gè)你可能感興趣的前端題
聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問(wèn)題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。郵件:2376512515@qq.com