Asynchronous code to synchronous built-in
So, not so long ago, I had to face the rather popular task of converting asynchronous code to synchronous as part of a loop. In my case, it was working with the AmazonAPI productSearch methods. Everything would be fine, but this API just doesn’t like it when it is accessed too often, and I needed to interrogate the status of products in a cycle.
In this article, I will use a practical example to talk about the implementation of the method that I used to solve my problem. Let's get started.
For implementation we will need: promises (I will use the q library), nodejs version with generator support, experimental asynchronous function (we will use setTimeout).
The result of this script will be:
As we see, all of our asynchronous calls go in synchronous mode. To support older versions (not supporting generators), I added the “oldIterator” function, which will work similarly to a generator.
PS : this code will work similarly in JavaScript, it’s enough to replace the “Q” library with the native “Promise”.
That's all, thanks for watching!
In this article, I will use a practical example to talk about the implementation of the method that I used to solve my problem. Let's get started.
For implementation we will need: promises (I will use the q library), nodejs version with generator support, experimental asynchronous function (we will use setTimeout).
var q = require("q");
function* itemGenerator(data)
{
var i, len = data.length;
for(i = 0; i < len; i++)
{
yield data[i];
}
}
function oldIterator(data)
{
var i = -1, len = data.length;
return {
"next": function()
{
i++;
return {
"done": i == len,
"value": data[i]
};
}
}
}
function main()
{
var def = q.defer(), items = [1, 2, 3, 4, 5];
(function foo(gen)
{
var genItem = gen.next(), item = genItem.value;
if(genItem.done)
{
def.resolve(true);
return;
}
console.log("start call for", item);
setTimeout(function()
{
console.log("end call for", item);
foo(gen);
});
})(itemGenerator(items))
return def.promise;
}
main().then(function(flag)
{
console.log("promise has been resolved", flag);
});
The result of this script will be:
> node async_sync.js
start call for 1
end call for 1
start call for 2
end call for 2
start call for 3
end call for 3
start call for 4
end call for 4
start call for 5
end call for 5
promise has been resolved true
As we see, all of our asynchronous calls go in synchronous mode. To support older versions (not supporting generators), I added the “oldIterator” function, which will work similarly to a generator.
PS : this code will work similarly in JavaScript, it’s enough to replace the “Q” library with the native “Promise”.
That's all, thanks for watching!