34

Can I count on nodeIDs mapping is completed every time doSomething() is called?

nodeIDs = $.map(nodeIDs, function(n){
    return n.match(/\d+$/);
});
doSomething(nodeIDs);

I thought all callbacks in node.js are asynchronous? I did read an article on general programming that callback could be synchronous but I am not sure about node.js?

nalply
  • 26,770
  • 15
  • 78
  • 101
bonchef
  • 371
  • 1
  • 3
  • 7
  • what is $ here? map takes a callback function to apply to each member of the list, not a callback when complete iteration is complete. – chovy Oct 07 '12 at 01:23
  • Thanks chovy. As for the $, I was just experimenting with the node-jquery module and didn't bother to edit that out. – bonchef Oct 07 '12 at 23:36

7 Answers7

53

JavaScript is also a functional programming language. What you have here is a «higher order function», a function which takes a function as a parameter. Higher order functions are synchronous (but see note below).

Sources:

map() is a typical example of a higher order function. It takes a function and applies it to all elements of an array. The definition sounds very «functional». This function is also not provided by Node. It is documented by MDN Array.prototype.map() and specified by ECMAScript 5.1.

To answer your question: Yes, doSomething(nodeIDs) is called after all elements have been applied.


Note: The higher order function is a concept of functional programming. JavaScript is functional, but also deeply seated in the practicality of executing code inside a browser or on the server. I would say that for example setTimeout() is not a higher order function even if it takes a function as a parameter because setTimeout() is not really purely functional because it uses time. Pure functionality is timeless. For example the result of map() doesn't depend on time. And that's what this question is really about. If something doesn't depend on time you execute it synchronously. Problem solved.

Thanks to Simon for challenging the definition of the higher order function in JavaScript.

nalply
  • 26,770
  • 15
  • 78
  • 101
  • Thanks nalply. Looking at the reference implementation of map() helps. – bonchef Oct 07 '12 at 23:49
  • *Higher order functions are synchronous* – really? setTimeout is also a higher-order function, but it is asynchronous. – Simon A. Eugster Aug 11 '16 at 13:14
  • @SimonA.Eugster You have a point. If you strictly define functions that take functions as parameters as «higher order» then asynchronous functions are also «higher order». What would you call synchronous functions which take functions as parameters? – nalply Aug 11 '16 at 13:29
  • @nalply We never looked at asynchronism in Functional Programming, cannot help with a term here. I am not even sure if it matters in the concept of functional programming whether a function is asynchronous or not. Wonder what specialists would answer :) – Simon A. Eugster Aug 11 '16 at 20:05
17

Yes, .map is synchronous. "Callback" does not imply "asynchronous".

  • 1
    Thanks Charmander. I meant to say 'when in doubt, assume callbacks can be called asynchronously at a different time'. So the real question is (see my comments above) - Generally how can I tell if a given library function is async or not? – bonchef Oct 06 '12 at 21:14
  • The node.js File functions for example are well documented, but others, such as array mapping I can't seem to find this particular piece of info. – bonchef Oct 06 '12 at 21:20
  • That's because they are not provided by Node. They belong to the V8 runtime. V8 implements ECMAScript. `Array.map()` is documented here: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/map. – nalply Oct 07 '12 at 15:41
3

import the async module to have an asynchronous 'map' method

var async = require('async');

var arr = ['1','2'];
async.map(arr, getInfo, function (e, r) {
  console.log(r);
});

function getInfo(name, callback) {
  setTimeout(function() {
    callback(null, name + 'new');
  }, 1000);
}
suda
  • 2,604
  • 1
  • 27
  • 38
Damien Romito
  • 9,801
  • 13
  • 66
  • 84
2

This function is synchronous - otherwise it couldn't return the result of the map operation.

Any callbacks that might take longer time (mainly due to IO) are asynchronous in nodejs - unless the method is explicitely marked as being synchronous (such as fs.readFileSync - but that doesn't use a callback). You probably confused that somehow.

ThiefMaster
  • 310,957
  • 84
  • 592
  • 636
  • Thanks ThiefMaster. I understand the part of Sync and Async versions of the IO functions and have used both in the past. To re-phrase my question better: given a segment of code, when there is no callbacks, I can assume synchronous flow. But when there are callbacks, there is no obvious way to confirm one-way or the other? If IOs are involved likely they are async. But in the map() case I wasn't so sure - neither nodejs nor the Javascript references seem to specify that. So how can I tell for the next library function I encounter? – bonchef Oct 06 '12 at 21:08
  • The docs state it. E.g. http://nodejs.org/api/fs.html#fs_fs_rename_oldpath_newpath_callback "asynchronous rename" – ThiefMaster Oct 06 '12 at 21:11
-1

There is useful lib awaiting. And map will help you.

Ivan Nosov
  • 15,395
  • 2
  • 16
  • 14
-1

use a forof (is synchronous):

let arr = ['fizz', 'buzz']
//example
    for (const item of arr) {
   //this Examp_func returns array
     console.log((await Examp_func(item )).length);
    }
-2

YES, map function is asynchronous and is part of ECMAScript. NodeJS uses map from that definition. Try running this code to see it in action.

const array = ['first','second']

function name(params) {
  setTimeout(
    () => console.log('name: ' + params),
    5000
  );
}

console.log('wait for 5 seconds')
array.map(v => {
  name(v)
})
TonyStark
  • 51
  • 5