The Continuation-Passing Style in JavaScript

The Continuation-Passing Style in JavaScript

ways of cps style implementation

In JavaScript, a callback is a function that is passed as an argument to another function and is invoked with the result when the operation completes. In functional programming, this way of propagating the result is called continuation-passing style (CPS). It simply indicates that a result is propagated by passing it to another function (the callback), instead of directly returning it to the caller.

Synchronous Continuation-Passing Style

Let’s take a look at a simple synchronous function:

function add(a, b) {
  return a + b;
}

This is the so-called direct style that represents the most common way of returning a result in synchronous programming. The result is directly passed back to the caller using the return instruction. An equivalent continuation-passing style of the preceding function would be:

function add(a, b, callback) {
  callback(a + b);
}

Now the add() function is a synchronous CPS function, which means that it will return a value only when the callback function completes its execution.

Asynchronous Continuation-Passing Style

Let’s make the preceding function asynchronous:

function addAsync(a, b, callback) {
  setTimeout(function() {
    callback(a + b);
  }, 100);
}

The setTimeout() is used to simulate an asynchronous invocation of the callback.

Now, let’s try to use this function and see how the order of the operations:

console.log('before');
addAsync(1, 2, function(result) {
  console.log('Result: ' + result);
});
console.log('after');

// before
// after
// Result: 3

Since setTimeout() triggers an asynchronous operation, it will not wait anymore for the callback to be executed, but instead, it returns immediately giving the control back to addAsync(), and then back to its caller. The following image shows how this works:

addAsync() operations addAsync() operations

When the asynchronous operation completes, the execution is then resumed starting from the callback provided to the asynchronous function that caused the unwinding. The execution will start from the Event Loop, so it will have a fresh stack. Thanks to closures in JavaScript, it is trivial to maintain the context of the caller of the asynchronous function, even if the callback is invoked at a different point in time and from a different location.

Non Continuation-Passing Style Callbacks

There’re several circumstances in which the presence of a callback argument might make you think that a function is asynchronous or is using a continuation-passing style; that’s not always true, let’s take, for instance, the map() method of the Array object:

let result = [1, 2, 7].map(function(element) {
  return element + 1;
})

The callback is just used to iterate over the elements of the array, and not to pass the result of the operation. The result is returned synchronously using a direct style.

THE END
Ads by Google

林宏

Frank Lin

Hey, there! This is Frank Lin (@flinhong), one of the 1.41 billion . This 'inDev. Journal' site holds the exploration of my quirky thoughts and random adventures through life. Hope you enjoy reading and perusing my posts.

YOU MAY ALSO LIKE

Practising closures in JavaScript

JavaScript Notes

2018.12.17

Practising closures in JavaScript

JavaScript is a very function-oriented language. As we know, functions are first class objects and can be easily assigned to variables, passed as arguments, returned from another function invocation, or stored into data structures. A function can access variable outside of it. But what happens when an outer variable changes? Does a function get the most recent value or the one that existed when the function was created? Also, what happens when a function invoked in another place - does it get access to the outer variables of the new place?

Using Liquid in Jekyll - Live with Demos

Web Notes

2016.08.20

Using Liquid in Jekyll - Live with Demos

Liquid is a simple template language that Jekyll uses to process pages for your site. With Liquid you can output complex contents without additional plugins.

Hands on IBM Cloud Functions with CLI

Tools

2020.10.20

Hands on IBM Cloud Functions with CLI

IBM Cloud CLI allows complete management of the Cloud Functions system. You can use the Cloud Functions CLI plugin-in to manage your code snippets in actions, create triggers, and rules to enable your actions to respond to events, and bundle actions into packages.

logout

神童诗

汪洙「宋代」

天子重英豪,文章教尔曹。

万般皆下品,惟有读书高。

少小须勤学,文章可立身。

满朝朱紫贵,尽是读书人。

学问勤中得,萤窗万卷书。

三冬今足用,谁笑腹空虚。

自小多才学,平生志气高。

别人怀宝剑,我有笔如刀。

朝为田舍郎,暮登天子堂。

将相本无种,男儿当自强。

学乃身之宝,儒为席上珍。

君看为宰相,必用读书人。

莫道儒冠误,诗书不负人。

达而相天下,穷则善其身。

遗子满赢金,何如教一经。

姓名书锦轴,朱紫佐朝廷。

古有千文义,须知学后通。

圣贤俱间出,以此发蒙童。

神童衫子短.袖大惹春风。

未去朝天子,先来谒相公。

年纪虽然小,文章日渐多。

待看十五六,一举便登科。

大比因时举,乡书以类升。

名题仙桂籍,天府快先登。

喜中青钱选,才高压俊英。

萤窗新脱迹,雁塔早题名。

年小初登第,皇都得意回。

禹门三级浪,平地一声雷。

一举登科目,双亲未老时。

锦衣归故里,端的是男儿。

玉殿传金榜,君恩赐状头。

英雄三百辈,附我步瀛洲。

慷慨丈夫志,生当忠孝门。

为官须作相,及第必争先。

宫殿召绕耸,街衢竞物华。

风云今际会,千古帝王家。

日月光天德,山河壮帝居。

太平无以报,愿上万年书。

久旱逢甘雨,他乡遇故知。

洞房花烛夜,金榜题名时。

土脉阳和动,韶华满眼新。

一支梅破腊,万象渐回春。

柳色浸衣绿,桃花映酒红。

长安游冶子,日日醉春风。

淑景余三月,莺花已半稀。

浴沂谁氏子,三叹咏而归。

数点雨余雨,一番寒食寒。

杜鹃花发处,血泪染成丹。

春到清明好,晴天锦绣纹。

年年当此节,底事雨纷纷。

风阁黄昏夜,开轩内晚凉。

月华在户白,何处递荷香?

一雨初收霁,金风特送凉。

书窗应自爽,灯火夜偏长。

庭下陈瓜果,云端闻彩车。

争如郝隆子,只晒腹中书。

九日龙山饮,黄花笑逐臣。

醉看风落帽,舞爱月留人。

昨日登高罢,今朝再举觞。

菊荷何太苦,遭此两重阳。

北帝方行令,天晴爱日和。

农工新筑土,天庆纳嘉禾。

檐外三竿日,新添一线长。

登台观气象,云物喜呈祥。

冬天更筹尽,春附斗柄回。

寒暄一夜隔,客鬓两年催。

解落三秋叶,能开二月花。

过江千尺浪,入竹万杆斜。

人在艳阳中,桃花映面红。

年年二三月,底事笑春风。

院落沉沉晓,花开白雪香。

一枝轻带雨,泪湿贵妃妆。

枝缀霜葩白,无言笑晓凤。

清芳谁是侣,色间小桃红。

倾国姿容别,多开富贵家。

临轩一赏后,轻薄万千花。

墙角一枝梅,凌寒独自开。

遥知不是雪,为有暗香来。

柯干如金石,心坚耐岁寒。

平生谁结友,宜共竹松看。

居可无君子,交情耐岁寒。

春风频动处,日日报平安。

春水满泗泽,夏云多奇峰。

秋月扬明辉,冬岭秀孤松。

诗酒琴棋客,风花雪月天。

有名闲富贵,无事散神仙。

道院迎仙客,书道隐相儒。

庭裁栖凤竹,池养化龙鱼。

春游芳草地,夏赏绿荷池。

秋饮黄花酒,冬吟白雪诗。