Development 開發

[Node.js] Callback VS Promise VS async/await

Here is an example that show you why you have to use async/await especially in many callback functions in a single task. Assume that we have a function which multiply ‘x’ by 2 (200 ms).

output = x * 2

Here is the function with a callback parameter.

function slowDoubleCallback(x, callback) {
    setTimeout(() => {
        callback(x * 2);
    }, 200);
}

If we would like to call it 10 times, in callback version would be like this:

// Callback Hell Version
let callBackAns = 0;
slowDoubleCallback(1, (ans) => {
    callBackAns += ans;
    slowDoubleCallback(2, (ans) => {
        callBackAns += ans;
        slowDoubleCallback(3, (ans) => {
            callBackAns += ans;
            slowDoubleCallback(4, (ans) => {
                callBackAns += ans;
                slowDoubleCallback(5, (ans) => {
                    callBackAns += ans;
                    slowDoubleCallback(6, (ans) => {
                        callBackAns += ans;
                        slowDoubleCallback(7, (ans) => {
                            callBackAns += ans;
                            slowDoubleCallback(8, (ans) => {
                                callBackAns += ans;
                                slowDoubleCallback(9, (ans) => {
                                    callBackAns += ans;
                                    slowDoubleCallback(10, (ans) => {
                                        callBackAns += ans;
                                        console.log("Callback: " + callBackAns);
                                    });
                                });
                            });
                        });
                    });
                });
            });
        });
    });
});

That is horrible, right? Now, make a Promise version. To do this, we need to modify the function to return Promise object:

function slowDouble(x) {
    return new Promise((resolve) => {
        setTimeout(() => {
            resolve(x * 2);
        }, 200);
    });
}

To call it 10 times, would be like this:

// Promise Version
let promiseAns = 0;
slowDouble(1).then((ans) => {
    promiseAns += ans;
    return slowDouble(2);
}).then((ans) => {
    promiseAns += ans;
    return slowDouble(3);
}).then((ans) => {
    promiseAns += ans;
    return slowDouble(4);
}).then((ans) => {
    promiseAns += ans;
    return slowDouble(5);
}).then((ans) => {
    promiseAns += ans;
    return slowDouble(6);
}).then((ans) => {
    promiseAns += ans;
    return slowDouble(7);
}).then((ans) => {
    promiseAns += ans;
    return slowDouble(8);
}).then((ans) => {
    promiseAns += ans;
    return slowDouble(9);
}).then((ans) => {
    promiseAns += ans;
    return slowDouble(10);
}).then((ans) => {
    console.log("Promise: " + (promiseAns + ans));
});

Much better in Promise version? Now in async/await version:

// async / await Version
(async () => {
    let ans = 0;
    ans += await slowDouble(1);
    ans += await slowDouble(2);
    ans += await slowDouble(3);
    ans += await slowDouble(4);
    ans += await slowDouble(5);
    ans += await slowDouble(6);
    ans += await slowDouble(7);
    ans += await slowDouble(8);
    ans += await slowDouble(9);
    ans += await slowDouble(10);
    console.log("async/await: " + ans);
})();

Extremely clear, isn’t it? Not just for readability. You could add for-loop here like structured programming which is difficult in callback/promise (Edit: a redditor pointed out that you can do this with Promise) version.

// async / await Version 2
(async () => {
    let ans = 0;
    for (let i = 1; i <= 10; i++) {
        ans += await slowDouble(i);
    }
    console.log("async/await Version 2: " + ans);
})();

Hope you could feel the benefit of async/await after read the example. Not saying callback is useless, it is still useful in a simple situation. However, it is much clear to write async/await in complicated situation.

Tested on: Node.js 8.10.0

Gist:
https://gist.github.com/louislam/a4ffc57fb9fd4596a0092d1054eabcee

Reddit Thread:
https://www.reddit.com/r/javascript/comments/85j6tu/for_beginners_i_wrote_an_article_to_help_you/

終於看得懂/懂得寫RegEx了 [SRL – Simple Regex Language]

對於 Regular Expression (RegEx),小弟總是有讀寫障礙似的,總是記不了那些 Syntax。當要 Debug 別人寫的 RegEx,簡直攞命。

近日在 Reddit 的 PHP Subreddit 看到有人出 POST 介紹 Simple Regex Language (SRL)。一試之下,發現異常地好用。寫法更似人類語言,好寫兼好看,易於Debug。非常易上手。

目前只有兩種方法試玩:(1) PHP 7 、 (2) 線上編譯器 (https://simple-regex.com/build)

以下是我簡單試用 SRL 讀取網址中的Name 和 Age:
(利申: 真的隨便簡單地試用一下SRL,不要問我為何 Match 不了 Subdomain 之類)

Live Demo: https://simple-regex.com/build/57d3949dddec6

SRL版本,基本上不懂SRL 的人都看得懂吧:

any of (literally “http://”, literally “https://”),
any of (letter, digit) at least 2 times,
literally “.”,
letter at least 2 times,
anything never or more,
literally “?”,
any of (literally “name”)
literally “=”,
capture (anything never or more) as “Name”,
literally “&”,
any of (literally “age”)
literally “=”,
capture (anything never or more) as “Age”,

Compile 出來的RegEx (汗):

/(?:(?:http:\/\/)|(?:https:\/\/))(?:[a-z]|[0-9]|[\.\-]){2,}(?:\.)[a-z]{2,}.*(?:\?)(?:(?:name))(?:=)(?<Name>.*)(?:&)(?:(?:age))(?:=)(?<Age>.*)/

測試:

louislam-pc-000343

 

Reddit Thread: https://www.reddit.com/r/PHP/comments/5068u1/ive_built_a_sqllike_language_that_compiles_to/