フロントエンド面接命題(二)-callback,promise,generator,async-await
9287 ワード
前言
この文章はフロントエンドアーキテクチャ、または段階的なフロントエンド開発者に適しています.vmwareフロントエンドアーキテクチャを面接したとき、callback、promise、generator、async-awaitについて聞かれました.
まずjavascriptの非同期の発展過程を振り返ってみましょう.
ES 6以前:
コールバック関数(callback);Nodejs expressではよく使われ、ajaxではよく使われます.
ES6:
promiseオブジェクト;Nodejsにはbluebird promiseの雛形が最初にあり、axiosでよく使われています.
generator関数;Nodejs koaフレームワークは使用率が高い.
ES7:
async/await構文;現在最もよく使われている非同期構文で、nodejs koa 2はこの構文を完全に使用しています.
コールバック関数callback
コールバック関数は実際にはパラメータです.1つの関数をパラメータとして別の関数に転送し、その関数が実行された後、転送されたこの関数を実行します.この過程をコールバックと呼ぶ.
コールバックの字面も理解して、先に本体の関数を処理して、更にコールバックの関数を処理して、例を挙げて、みんなが理解するのに便利です.
上の例はよく理解して、まず主体関数Aを実行して、結果を印刷します:私はテーマ関数です;コールバック関数callback、すなわちBを実行し、結果を印刷します.コールバック関数です.
promiseオブジェクト
promiseオブジェクトは、非同期操作の最終的な完了(または最終的な失敗)とその結果の表現に使用されます.
簡単に言えば、非同期リクエストを処理します.私たちはよく断言をします.もし私が勝ったら、あなたは私と結婚して、負けたら、私はあなたと結婚します.これがpromiseの中国語の意味です:断言して、1つの成功、1つの失敗.
例を挙げると、皆さんの理解に便利です.
promiseコンストラクション関数のパラメータは1つの関数であり、プロセッサ関数と呼ばれ、プロセッサ関数は2つの関数resloveとrejectをパラメータとして受信し、非同期操作が順調に実行されるとreslove関数を実行し、非同期操作で異常が発生するとreject関数数を実行する.resolveで入力された値はthenメソッドで取得でき、rejectで入力された値はchatchメソッドで取得できます.
thenとcatchは同じpromiseオブジェクトを返すため、チェーン呼び出しを行うことができます.
generator関数
ES 6の新しい特性generator関数(面接の時にここに掛けます)は、中国語でジェネレータと訳され、以前の関数の中のコードが呼び出されるか、呼び出されないか、一時停止できる場合はありません.generatorはコードを実行待ちに一時停止させ、ジェネレータを定義するのは簡単で、関数の名前に*番号を付けて、使用上も普通の関数とは違います.
例を挙げると、皆さんの理解に便利です.
上には簡単なgenerator宣言の例があります.
generator関数は直接呼び出すことはできません.generator関数を直接呼び出すと、そのオブジェクトのnext()メソッドを呼び出すだけで関数のコードを実行できます.
この関数を実行します.
実はgeneratorを単独で紹介するのはあまり価値がありません.key yieldと協力してこそ、generatorの価値を本当に発揮することができます.yieldは生Generator関数のコードロジックを複数の部分に分割し,以下に上のジェネレータ関数を書き換えることができる.
このコードが最初のyieldで実行されると停止することがわかりますが、中のすべてのコードを実行するにはnext()メソッドを繰り返し呼び出さなければなりません.
一例では、generator関数とコールバック関数の違いを説明します.
コールバック関数:
これは典型的なコールバックネストであり、多すぎるコールバックネストはコードの可読性とメンテナンス性を大幅に低下させ、憎らしいコールバック地獄を形成している.ある日、10個のファイルを順番に読み取らせたら、10層をネストしなければならない.また、需要がさらに大きくなり、読み取り順序が変わったらb.txtを先に読み、再びa.txtを変えなければならないと考えてみてください.それは本当に爽やかではありません.
generator関数:
generator関数の強さは、いくつかの実装の詳細を通じて非同期プロセスを隠すことができ、コードを単一スレッド、同期構文のコードスタイルを維持することができます.このような構文は、非同期の構文フォーマットを同時に操作する必要がなく、プログラムのステップ/文の流れを自然に表現することができます.
async-await
async関数はpromiseオブジェクトを返し、async関数で直接量を返すとasyncはPromiseを通過する.resolveはPromiseオブジェクトにカプセル化されます.この直接量はpromiseオブジェクトのthenメソッドを呼び出すことで取得できます.
ではasync関数が値を返さないとどうなるのでしょうか.
awaitは現在のasyncの実行を一時停止し、awaitはawait後の式の処理が完了するまでコードの実行をブロックし、コードは下に実行されません.await後の式は、Promiseオブジェクトでも待機する値でも構いません.awaitがPromiseオブジェクトである場合、awaitは忙しくなり、後のコードをブロックしてPromiseオブジェクトresolveを待ってからresolveの値をawait式の演算結果として得ます.
ブロックという言葉を見て、慌てないでください.async/awaitは文法糖にすぎません.コードの実行は複数のcallbackネスト呼び出しと区別されていません.本質は同期コードではありません.コードの論理を考えるときに同期の思考で考えることができます.復調地獄を避けることができます.簡単に言えば、async/awaitは同期の思考で非同期のコードを書くことです.だからasync/awaitはnodeの同時数に影響しないで、みんなは大胆にプロジェクトに応用することができます!
Promiseオブジェクトでない場合、await式の演算結果は待つものです.
例を挙げると、皆さんの理解に便利です.
転載先:https://www.cnblogs.com/peiyu1988/p/9204976.html
この文章はフロントエンドアーキテクチャ、または段階的なフロントエンド開発者に適しています.vmwareフロントエンドアーキテクチャを面接したとき、callback、promise、generator、async-awaitについて聞かれました.
まずjavascriptの非同期の発展過程を振り返ってみましょう.
ES 6以前:
コールバック関数(callback);Nodejs expressではよく使われ、ajaxではよく使われます.
ES6:
promiseオブジェクト;Nodejsにはbluebird promiseの雛形が最初にあり、axiosでよく使われています.
generator関数;Nodejs koaフレームワークは使用率が高い.
ES7:
async/await構文;現在最もよく使われている非同期構文で、nodejs koa 2はこの構文を完全に使用しています.
コールバック関数callback
コールバック関数は実際にはパラメータです.1つの関数をパラメータとして別の関数に転送し、その関数が実行された後、転送されたこの関数を実行します.この過程をコールバックと呼ぶ.
コールバックの字面も理解して、先に本体の関数を処理して、更にコールバックの関数を処理して、例を挙げて、みんなが理解するのに便利です.
function A(callback){
console.log(" ");
callback();
}
function B(){
console.log(" ");
}
A(B);
/*
*/
上の例はよく理解して、まず主体関数Aを実行して、結果を印刷します:私はテーマ関数です;コールバック関数callback、すなわちBを実行し、結果を印刷します.コールバック関数です.
promiseオブジェクト
promiseオブジェクトは、非同期操作の最終的な完了(または最終的な失敗)とその結果の表現に使用されます.
簡単に言えば、非同期リクエストを処理します.私たちはよく断言をします.もし私が勝ったら、あなたは私と結婚して、負けたら、私はあなたと結婚します.これがpromiseの中国語の意味です:断言して、1つの成功、1つの失敗.
例を挙げると、皆さんの理解に便利です.
promiseコンストラクション関数のパラメータは1つの関数であり、プロセッサ関数と呼ばれ、プロセッサ関数は2つの関数resloveとrejectをパラメータとして受信し、非同期操作が順調に実行されるとreslove関数を実行し、非同期操作で異常が発生するとreject関数数を実行する.resolveで入力された値はthenメソッドで取得でき、rejectで入力された値はchatchメソッドで取得できます.
thenとcatchは同じpromiseオブジェクトを返すため、チェーン呼び出しを行うことができます.
function readFileByPromise("a.txt"){
// promise
return new Promise((resolve,reject)=>{
fs.readFile(path,"utf8",function(err,data){
if(err)
reject(err);
else
resolve(data);
})
})
}
//
readFileByPromise("a.txt").then( data =>{
//
console.log(data);
}).catch( error =>{
// ,
console.log(error);
})
generator関数
ES 6の新しい特性generator関数(面接の時にここに掛けます)は、中国語でジェネレータと訳され、以前の関数の中のコードが呼び出されるか、呼び出されないか、一時停止できる場合はありません.generatorはコードを実行待ちに一時停止させ、ジェネレータを定義するのは簡単で、関数の名前に*番号を付けて、使用上も普通の関数とは違います.
例を挙げると、皆さんの理解に便利です.
function *Calculate(a,b){
let sum=a+b;
console.log(sum);
let sub=a-b;
console.log(sub);
}
上には簡単なgenerator宣言の例があります.
generator関数は直接呼び出すことはできません.generator関数を直接呼び出すと、そのオブジェクトのnext()メソッドを呼び出すだけで関数のコードを実行できます.
let gen=Calculate(2,7);
この関数を実行します.
gen.next();
/*
9
-5
*/
実はgeneratorを単独で紹介するのはあまり価値がありません.key yieldと協力してこそ、generatorの価値を本当に発揮することができます.yieldは生Generator関数のコードロジックを複数の部分に分割し,以下に上のジェネレータ関数を書き換えることができる.
function *Calculate(a,b){
let sum=a+b;
yield console.log(sum);
let sub=a-b;
yield console.log(sub);
}
let gen=Calculate(2,7);
gen.next();
/*
9*/
このコードが最初のyieldで実行されると停止することがわかりますが、中のすべてのコードを実行するにはnext()メソッドを繰り返し呼び出さなければなりません.
let gen=Calculate(2,7);
gen.next();
gen.next();
/*
9
-5*/
一例では、generator関数とコールバック関数の違いを説明します.
コールバック関数:
fs.readFile("a.txt",(err,data)=>{
if(!err){
console.log(data);
fs.readFile("b.txt",(err,data)=>{
if(!err)
console.log(data);
})
}
})
これは典型的なコールバックネストであり、多すぎるコールバックネストはコードの可読性とメンテナンス性を大幅に低下させ、憎らしいコールバック地獄を形成している.ある日、10個のファイルを順番に読み取らせたら、10層をネストしなければならない.また、需要がさらに大きくなり、読み取り順序が変わったらb.txtを先に読み、再びa.txtを変えなければならないと考えてみてください.それは本当に爽やかではありません.
generator関数:
function readFile(path) {
fs.readFile(path,"utf8",function(err,data){
it.next(data);
})
}
function *main() {
var result1 = yield readFile("a.txt");
console.log(result1);
var result2 = yield readFile("b.txt");
console.log(result2);
var result3 = yield readFile("c.txt");
console.log(result3);
}
var it = main();
it.next();
generator関数の強さは、いくつかの実装の詳細を通じて非同期プロセスを隠すことができ、コードを単一スレッド、同期構文のコードスタイルを維持することができます.このような構文は、非同期の構文フォーマットを同時に操作する必要がなく、プログラムのステップ/文の流れを自然に表現することができます.
async-await
async関数はpromiseオブジェクトを返し、async関数で直接量を返すとasyncはPromiseを通過する.resolveはPromiseオブジェクトにカプセル化されます.この直接量はpromiseオブジェクトのthenメソッドを呼び出すことで取得できます.
async function test(){
return "Hello World";
}
var result=test();
console.log(result);
// Promise { 'Hello World' }
ではasync関数が値を返さないとどうなるのでしょうか.
async function test(){
}
var result=test();
console.log(result);
// Promise { undefined }
awaitは現在のasyncの実行を一時停止し、awaitはawait後の式の処理が完了するまでコードの実行をブロックし、コードは下に実行されません.await後の式は、Promiseオブジェクトでも待機する値でも構いません.awaitがPromiseオブジェクトである場合、awaitは忙しくなり、後のコードをブロックしてPromiseオブジェクトresolveを待ってからresolveの値をawait式の演算結果として得ます.
ブロックという言葉を見て、慌てないでください.async/awaitは文法糖にすぎません.コードの実行は複数のcallbackネスト呼び出しと区別されていません.本質は同期コードではありません.コードの論理を考えるときに同期の思考で考えることができます.復調地獄を避けることができます.簡単に言えば、async/awaitは同期の思考で非同期のコードを書くことです.だからasync/awaitはnodeの同時数に影響しないで、みんなは大胆にプロジェクトに応用することができます!
Promiseオブジェクトでない場合、await式の演算結果は待つものです.
例を挙げると、皆さんの理解に便利です.
function A() {
return "Hello ";
}
async function B(){
return "World";
}
async function C(){
//
var s1=await A();
// promise ,await promise resolve , "World"
var s2=await B();
console.log(s1+s2);
}
C();
// "Hello World"
転載先:https://www.cnblogs.com/peiyu1988/p/9204976.html