JavaScript非同期promiseからawaitへ
5520 ワード
一、コールバックからPromiseまで、なぜそれを使うのか
非同期タスクを実行するときに、非同期タスクの終了時に呼び出されるコールバック関数が使用されます.将来実行される共通点があります.例えばnode.jsでの非同期読み込みファイル:
ajaxリクエスト関数を書いたように、
タイマータスクもあります
このようにコールバックを使用する方法は問題ないようですが、コールバック関数に非同期タスクがある場合、多層コールバック、すなわちコールバック地獄の問題が発生する可能性があります.多層コールバックにより、コードの可読性とメンテナンス性が低下します.
Promiseは私たちのために何をしましたか?
簡単に言えば、Promiseは非同期タスクをオブジェクトにパッケージし、非同期タスクが完了した後に実行する関数をthenメソッドに渡し、resolveで関数を呼び出します.上記のタイマタスクを次のように書き換えることができます.
タイミング・タスクでまたタイミング・タスクを実行する場合は、コールバックをネストするのではなく、このように書くことができます.
Promiseの役割:非同期タスクが完了した後の処理関数を場所を変えて置く:thenメソッドに伝え、チェーン呼び出しをサポートし、階層的なコールバックを回避する. はエラーをキャプチャします.コードエラーでも手動reject()でも、これらのエラーを1つの関数で処理できます.
二、あなたが知らないかもしれないPromiseの詳細
Promiseを使うと非同期コードになります
コードに非同期操作がなかったとしても
この点は,イベントループに関する知識を調べることができる.
catchのもう一つの書き方
実はcatchは意味化された文法糖にすぎず、thenでエラーを直接処理することもできます.
thenメソッドまたはcatchメソッドは常にpromiseオブジェクトを返します
thenメソッドの最初のパラメータと2番目のパラメータ(またはcatchのパラメータ)は、呼び出し条件が異なるだけです.
promiseオブジェクトを返す場合:
パッケージを使用すると、promiseオブジェクトの最後の状態を常に成功させることができます.たとえば、次のようにします.
task関数を呼び出すには、外にcatchキャプチャエラーを追加する必要がありますが、パッケージすることができます.
catchでエラーを報告しても後でキャプチャを続けることができます.catchもpromiseオブジェクトを返すからですか.
三、await:新しい文法糖
awaitは非同期コードを同期コードのようにし、シリアルの非同期呼び出しをより自然に書く.awaitの後ろに値またはpromiseオブジェクトがあり、値の場合は直接戻ります.promiseオブジェクトの場合、promiseオブジェクトが成功した後の戻り値を受け入れます.またはawaitの後にasync関数を呼び出す
awaitを使用するには、awaitが成功にのみ関心を持っているため、エラーのキャプチャに注意してください.
このように書くとエラーが報告されるので、task関数でエラーをキャプチャするか、task呼び出し時にキャプチャします.
awaitを使用すると、コードが非同期になります.
完~
非同期タスクを実行するときに、非同期タスクの終了時に呼び出されるコールバック関数が使用されます.将来実行される共通点があります.例えばnode.jsでの非同期読み込みファイル:
fs.readFile('/etc/passwd', (err, data) => {
if (err) throw err;
console.log(data);
});
ajaxリクエスト関数を書いたように、
// ,
const request = function(callback){
let xhr = new XMLHttpRequest();
// .....
xhr.onreadystatechange = function(){
callback(xhr)
}
}
//
request(function(xhr){
if (xhr.readyState === 4 && xhr.status === 200) {
// ....
} else {
//....
}
})
タイマータスクもあります
const doSomethingLater = function(delay, callback){
setTimeout(callback, delay*1000)
}
//
doSomethingLater(1, function(){
// .....
})
このようにコールバックを使用する方法は問題ないようですが、コールバック関数に非同期タスクがある場合、多層コールバック、すなわちコールバック地獄の問題が発生する可能性があります.多層コールバックにより、コードの可読性とメンテナンス性が低下します.
Promiseは私たちのために何をしましたか?
簡単に言えば、Promiseは非同期タスクをオブジェクトにパッケージし、非同期タスクが完了した後に実行する関数をthenメソッドに渡し、resolveで関数を呼び出します.上記のタイマタスクを次のように書き換えることができます.
const doSomethingLater = function(delay){
return new Promise((resolve)=>{
setTimeout(()=>{ resolve() }, delay*1000)
})
}
doSomethingLater(1)
.then(()=>{
console.log(' 1')
})
タイミング・タスクでまたタイミング・タスクを実行する場合は、コールバックをネストするのではなく、このように書くことができます.
doSomethingLater(1)
.then(() => {
console.log(' 1')
return doSomethingLater(1)
})
.then(() => {
console.log(' 2')
})
Promiseの役割:
二、あなたが知らないかもしれないPromiseの詳細
Promiseを使うと非同期コードになります
コードに非同期操作がなかったとしても
Promise.resolve()
.then(() => {
console.log(1)
})
console.log(2)
// 2
// 1
この点は,イベントループに関する知識を調べることができる.
catchのもう一つの書き方
Promise.reject('error')
.then(() => {
})
.catch((err) => {
console.log(err)
})
//
Promise.reject('error')
.then(() => {
})
.then(null, (err) => {
console.log(err)
})
//
Promise.reject('error')
.then(() => {
}, (err) => {
console.log(err)
})
実はcatchは意味化された文法糖にすぎず、thenでエラーを直接処理することもできます.
thenメソッドまたはcatchメソッドは常にpromiseオブジェクトを返します
thenメソッドの最初のパラメータと2番目のパラメータ(またはcatchのパラメータ)は、呼び出し条件が異なるだけです.
Promise.resolve()
.then(() => {
return 1
})
.then((res) => {
console.log(res) // 1
})
Promise.resolve()
.then(() => {
//
})
.then((res) => {
console.log(res) // undefined, undefined
})
promiseオブジェクトを返す場合:
Promise.resolve()
.then(() => {
return new Promise((resolve) => {
resolve(2)
})
})
.then((res) => {
console.log(res) // 2, promise
})
パッケージを使用すると、promiseオブジェクトの最後の状態を常に成功させることができます.たとえば、次のようにします.
const task = () => {
return new Promise((resolve, reject) => {
// ....
})
}
task()
.then((res) => {
console.log(res)
})
.catch((err) => {
console.log(err)
})
task関数を呼び出すには、外にcatchキャプチャエラーを追加する必要がありますが、パッケージすることができます.
const task = () => {
return new Promise((resolve, reject) => {
// ....
})
.then((res) => {
return {
status: 'success',
value: res
}
})
.catch((err) => {
return {
status: 'fail',
value: err
}
})
}
// !
task()
.then((result) => {
console.log(result)
})
catchでエラーを報告しても後でキャプチャを続けることができます.catchもpromiseオブジェクトを返すからですか.
Promise.reject('first error')
.catch((err) => {
console.log(err)
throw new Error('second error')
})
.then(null, (err) => {
console.log(err)
})
三、await:新しい文法糖
awaitは非同期コードを同期コードのようにし、シリアルの非同期呼び出しをより自然に書く.awaitの後ろに値またはpromiseオブジェクトがあり、値の場合は直接戻ります.promiseオブジェクトの場合、promiseオブジェクトが成功した後の戻り値を受け入れます.またはawaitの後にasync関数を呼び出す
const task = async () => {
return new Promise((resolve, reject) => {
resolve(1)
})
}
const handle = async () => {
let value = await task()
console.log(value)
}
handle() // 1
awaitを使用するには、awaitが成功にのみ関心を持っているため、エラーのキャプチャに注意してください.
const task = async () => {
return new Promise((resolve, reject) => {
reject(1)
})
}
const handle = async () => {
let value = await task()
console.log(value)
}
handle()
このように書くとエラーが報告されるので、task関数でエラーをキャプチャするか、task呼び出し時にキャプチャします.
const task = async () => {
return new Promise((resolve, reject) => {
reject(1)
})
}
const handle = async () => {
let value = await task().catch((err) => { console.log(err) })
console.log(value) // undefine, , , value
}
awaitを使用すると、コードが非同期になります.
const handle = async () => {
let value = await 1
console.log(value)
}
handle()
console.log(2)
// 2
// 1
完~