ES 6のPromiseの面接問題について
10138 ワード
説明
最近Promiseの知識を復習していますので、いくつかの問題を解いてみました.
テーマ1
まずPromiseが新規作成されたらすぐ実行されるので、まず1,2を出力します.
答え
一度状態が変わると、もう変わりません.したがって、コードの
Promiseは一回だけレスリングできます.残りのコールは無視されます.したがって、二回目の
答え
答え
赤信号は三秒に一回、青信号は一秒に一回、黄灯は二秒に一回点灯します.どのように3つのライトを交互に点灯させますか?(Promseで実現)3つの点灯関数は既に存在します.
赤信号は三秒に一回、青信号は一秒に一回、黄灯は二秒に一回、つまり三秒で一回のred関数を実行して、二秒に一回のグリーン関数を実行して、一秒に一回のyellow関数を実行して、絶えず交互に明かりを点灯します.
答え
mergPromise関数を実現して、転送された配列を順番に順を追って実行して、しかも帰ってくるデータを順番に配列dataの中に置きます.
まず
答え
以下のコードは最後に何を出力しますか?
この問題は実は
今回は、JavaScriptの実行メカニズムを徹底的に理解します.
イベントサイクル
先にマクロタスクを実行し、メインscript、new Promiseは直ちに実行し、【3】を出力し、pというnew Promise操作を実行し、【7】を出力し、setTimeoutを発見したら、次のタスクキュー(Event Que)に戻ります.
第二ラウンドイベント循環
まずマクロタスクの中の、つまりsetTimeoutのコールバックを実行して【5】を出力します.
答え
8つのピクチャリソースがあるurlは、配列
問題の意味は私達がこのようにする必要があって、先に3枚のピクチャーを同時に請求して、1枚のピクチャーがロードし終わった後に、また引き続き1枚のピクチャーの要求を開始して、併発数を3つに維持させて、ロードするピクチャーまですべて要求を開始します.
Promiseで実現すると、3つの画像リソースを同時に要求して、3つのPromiseを得ることができます.これは
答え
このいくつかの問題は、Promiseの基礎知識をテストするものもあれば、Promiseに対して活用するものもあります.これらの問題がよくできたら、Promiseに対する理解はいいと思います.
最後に、もし文章の中に足りないところや間違ったところがあったら、友達に指摘してもらって、ありがとうございます.文章の内容が足りないと感じたら、最後にテーマに関する文章があります.見てもいいです.
参照
ECMAScript 6入門——阮一峰
ES 6シリーズの私達はPromiseについて話します.
Promise応用に関する面接問題
アリの先端テスト問題--ES 6のPromise関数の理解と応用について
今回は、JavaScriptの実行メカニズムを徹底的に理解します.
つのPromiseの面接試験問題
ES 6原生Promiseのあらゆる方法紹介(添付の応用シーンテーマ)
Promise非同期プロセス制御
最近Promiseの知識を復習していますので、いくつかの問題を解いてみました.
テーマ1
const promise = new Promise((resolve, reject) => {
console.log(1);
resolve();
console.log(2);
})
promise.then(() => {
console.log(3);
})
console.log(4);
解析まずPromiseが新規作成されたらすぐ実行されるので、まず1,2を出力します.
Promise.then()
内部のコードはイベントサイクルの最後にすぐ実行されますので、引き続き4を出力します.最後に3を出力します.答え
1
2
4
3
タイトル2const 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オブジェクトの状態を“ ” “ ”
から(pending resolved
から)非同期動作が成功したときに呼び出し、非同期動作の結果をパラメータとして伝達する.reject
は、Promiseオブジェクトの状態を“ ” “ ”
から(pending rejected
から)非同期動作に失敗したときに呼び出し、非同期動作が報告されたエラーをパラメータとして伝達する.一度状態が変わると、もう変わりません.したがって、コードの
reject('error');
は機能しない.Promiseは一回だけレスリングできます.残りのコールは無視されます.したがって、二回目の
resolve('success2');
も役に立たない.答え
then: success1
タイトル3Promise.resolve(1)
.then(2)
.then(Promise.resolve(3))
.then(console.log)
解析Promise.resolve
方法のパラメータが元の値である場合、またはthen
方法を持たないオブジェクトである場合、Promise.resolve
方法は新しいPromise
オブジェクトに戻り、状態はresolved
、Promise.resolve
方法のパラメータが同時にコールバック関数に送られる.then
方法で許容されるパラメータは関数であり、伝達されるものが関数ではない場合は、実際にはthen(null)
と解釈され、これは、前のPromise
の結果が以下の通りになる.答え
1
テーマ4赤信号は三秒に一回、青信号は一秒に一回、黄灯は二秒に一回点灯します.どのように3つのライトを交互に点灯させますか?(Promseで実現)3つの点灯関数は既に存在します.
function red() {
console.log('red');
}
function green() {
console.log('green');
}
function yellow() {
console.log('yellow');
}
解析赤信号は三秒に一回、青信号は一秒に一回、黄灯は二秒に一回、つまり三秒で一回のred関数を実行して、二秒に一回のグリーン関数を実行して、一秒に一回のyellow関数を実行して、絶えず交互に明かりを点灯します.
答え
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();
タイトル5mergPromise関数を実現して、転送された配列を順番に順を追って実行して、しかも帰ってくるデータを順番に配列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
は全部関数です.これらの関数が実行されるとPromise
に戻ります.テーマの要求によってこの三つの関数を順番に実行すればいいです.そして結果をdata
に入れます.しかし、これらの関数はすべて非同期です.順番に実行したいです.そして1、2、3を出力するのはそんなに簡単ではありません.例を見てください.function A() {
setTimeout(function () {
console.log('a');
}, 3000);
}
function B() {
setTimeout(function () {
console.log('b');
}, 1000);
}
A();
B();
// b
// a
例では、A
、B
が順次実行されていますが、出力の結果はb
、a
は、これらの非同期関数については、順番に1つを実行しきれず、後の1つを実行します.この問題はPromise
を使って非同期の流れを制御することを試験して、私達は方法を考えて、これらの関数を譲って、1つの実行が終わった後に、更に次を実行して、解答を見ましょう.答え
//
var data = [];
// Promise.resolve , resolved Promise 。
var sequence = Promise.resolve();
ajaxArray.forEach(function (item) {
// then ,
// then ,
// data , data 。
// sequence , Promise
sequence = sequence.then(item).then(function (res) {
data.push(res);
return data;
});
})
// , Promise, sequence, [[PromiseValue]] data,
// data( ) , then 。
return sequence;
タイトル6以下のコードは最後に何を出力しますか?
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);
解析この問題は実は
Promise
との関係があまり大きくないです.JS執行メカニズムを理解してこそ、この問題をうまく解決できます.JS執行メカニズムがよく分からない友達にこの文章を紹介してください.今回は、JavaScriptの実行メカニズムを徹底的に理解します.
イベントサイクル
先にマクロタスクを実行し、メインscript、new Promiseは直ちに実行し、【3】を出力し、pというnew Promise操作を実行し、【7】を出力し、setTimeoutを発見したら、次のタスクキュー(Event Que)に戻ります.
console.log(4)
を実行し、【4】を出力し、マクロタスクの実行が終了します.また、マイクロタスクを実行し、then 1を実行し、【1】を出力し、then 2を実行し、【2】を出力します.これで第1ラウンドは終了します.第二ラウンドの実行を開始します.第二ラウンドイベント循環
まずマクロタスクの中の、つまりsetTimeoutのコールバックを実行して【5】を出力します.
resolve(6)
は有効ではありません.pというPromiseの状態が一旦変わると、変化しないからです.答え
3
7
4
1
2
5
タイトル78つのピクチャリソースがあるurlは、配列
urls
に格納されている.(urls = ['http://example.com/1.jpg', ...., 'http://example.com/8.jpg'])
です.もう一つの関数function loadImg
があります.urlリンクを入力して、Promiseに戻ります.このPromiseは写真のダウンロードが完了した時にreolveをダウンロードしました.失敗したら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
})
};
解析問題の意味は私達がこのようにする必要があって、先に3枚のピクチャーを同時に請求して、1枚のピクチャーがロードし終わった後に、また引き続き1枚のピクチャーの要求を開始して、併発数を3つに維持させて、ロードするピクチャーまですべて要求を開始します.
Promiseで実現すると、3つの画像リソースを同時に要求して、3つのPromiseを得ることができます.これは
promises
と呼ばれる行列を作ってください.そしてPromise.raceを呼び出して、一番速い状態のPromiseに戻ります.そして、配列から(promises
)でこのPromiseオブジェクトを削除し、新しいPromiseを追加して、全部のurlが取り除かれるまでPromise.allを使って、一回の配列(promises
)の中で状態を変えていない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 = [];
//
promises = sequence.splice(0, limit).map((url, index) => {
// index promises , Promise.race
return handler(url).then(() => {
return index
});
});
// reduce
return sequence.reduce((last, url, currentIndex) => {
return last.then(() => {
// Promise
return Promise.race(promises)
}).catch(err => {
// catch then
//
console.error(err)
}).then((res) => {
// Promise Promise
promises[res] = handler(sequence[currentIndex]).then(() => { return res });
})
}, Promise.resolve()).then(() => {
return Promise.all(promises)
})
}
limitLoad(urls, loadImg, 3)
/*
limitLoad Promise, ,
limitLoad(urls, loadImg, 3).then(() => {
console.log(' ');
}).catch(err => {
console.error(err);
})
*/
締め括りをつけるこのいくつかの問題は、Promiseの基礎知識をテストするものもあれば、Promiseに対して活用するものもあります.これらの問題がよくできたら、Promiseに対する理解はいいと思います.
最後に、もし文章の中に足りないところや間違ったところがあったら、友達に指摘してもらって、ありがとうございます.文章の内容が足りないと感じたら、最後にテーマに関する文章があります.見てもいいです.
参照
ECMAScript 6入門——阮一峰
ES 6シリーズの私達はPromiseについて話します.
Promise応用に関する面接問題
アリの先端テスト問題--ES 6のPromise関数の理解と応用について
今回は、JavaScriptの実行メカニズムを徹底的に理解します.
つのPromiseの面接試験問題
ES 6原生Promiseのあらゆる方法紹介(添付の応用シーンテーマ)
Promise非同期プロセス制御