JS Async / Await vs Promise vs Callbacks

Sep 14 2020

これらの違いを理解しようとしています。3。コールバックと約束は明確ですが、async / awaitの使用法がわかりません。それが約束の構文糖衣であることは知っていますが、私が試したものはうまくいきませんでした。私はこれをすべて理解しようとしたコードの一部を共有しています...

配列で試しました

var array = [1,2,3];

および2つの機能

  • get() 1秒で実行&コンソール array
  • post(item) 2秒で実行し、新しいアイテムをプッシュします array

さて、私が取得したいのは、コンソールでの結果が表示されpostないように、メソッドが最初とget後に実行される必要がある[1,2,3,4]ということです[1,2,3]

折り返し電話

function get() {
    setTimeout(() => console.log(array), 1000);
}

function post(item, callback) {
    setTimeout(() => {
        array.push(item);
        callback();
    }, 2000);
}

function init() {
    post(4, get);
    // returns [1,2,3,4] ✅
}

正常に動作しますが、コールバックが多すぎると、コードが乱雑になります...だから、

約束する

function get() {
    setTimeout(() => console.log(array), 1000);
}

function post(item) {
    return new Promise((resolve, reject) => setTimeout(() => {
        array.push(item)
        resolve();
    }, 2000));
}

function init() {
    post(4).then(get);
    // returns [1,2,3,4] ✅
}

よりクリーンなコードでOK。しかし、それでも複数のthen呼び出し...今、

非同期/待機

function get() {
    setTimeout(() => console.log(array), 1000);
}

function post(item) {
    setTimeout(() => {
        array.push(item)
    }, 2000);
}

async function init() {
    await post(4);
    get();
    // returns [1,2,3] ❌

    await post(4);
    await get();
    // returns [1,2,3] ❌

    post(4);
    await get();
    // returns [1,2,3] ❌
}

はるかにクリーンなバージョンですが、どちらの方法でも機能しませんでした...私もこれを試しました(両方の関数(post&get)を非同期に変換してで呼び出すthen)

async function get() {
    setTimeout(() => console.log(array), 1000);
}

async function post(item) {
    setTimeout(() => {
        array.push(item)
    }, 2000);
}

async function init() {
    post(4).then(get);
    // returns [1,2,3] ❌
}

しかし、それでも役に立たない。だから私はこの機能(つまり非同期/待機)について完全に混乱しています。この例について詳しく説明してください。また、これと同じコンテキストでPromise.resolve&について教えてくださいPromise.all!ありがとう

回答

3 Quentin Sep 13 2020 at 22:35

asyncそして、awaitするツールです約束を管理します

await post(4);

ここでは、返される約束postが解決されるのを待っています。

function post(item) {
    setTimeout(() => {
        array.push(item)
    }, 2000);
}

ただし、post promiseは返されないため、何も役に立ちません。

あなたはpost以前に約束を持っての実用的な実装を持っていました。だからそれを使用してください:

function post(item) {
    return new Promise((resolve, reject) => setTimeout(() => {
        array.push(item)
        resolve();
    }, 2000));
}
2 trincot Sep 13 2020 at 22:38

あなたの試みとasyncし、await約束解決は何も使用しない遅延の後に。現状では、async定義したすべての関数は、すぐに解決されるpromiseを返します。

よく使うユーティリティ機能を使いたくなるでしょう。を使用して、指定されたミリ秒数後に解決するPromiseを返しますsetTimeout。

// utility function
let delay = ms => new Promise(resolve => setTimeout(resolve, ms));

let array = [1, 2, 3];

async function get() {
    await delay(1000);
    console.log(array);
}

async function post(item) {
    await delay(1000);
    array.push(item)
}

async function init() {
    await post(4);
    await get();
}

init();
console.log("wait for it...");

1 tawfiknasser Sep 13 2020 at 22:31

PROMISEで行ったことと同様です。

ポストsetTimeoutをpromiseでラップし、それを返します。
settimeoutの本体内でresolveを呼び出します。

function post(item) {
 return new Promise((resolve)=>{
   setTimeout(() => {
     array.push(item)
     resolve()
   }, 2000);
 })
}

その後、あなたはそれをそのように使うことができます:

async function init() {
    await post(4);
    get();
    }