How should I use the callback to get the desired outcome? - javascript

Hello there I am getting the desired result when am using promise but how should I implement it with callback when am returning something from the function.
result with promise
const first = () => {
return ("I am first");
}
const second = () => {
return new Promise((resolve,reject) => {
setTimeout(()=>{
resolve("I am second");
},1000);
})
}
const third = () => {
return("I am third");
}
//using promise
const solve = async () => {
var f = first();
console.log(f);
var ans = await second();
console.log(ans);
var t = third();
console.log(t);
}
solve();
*** using callback ***
const first = () => {
return "I am first";
}
var temp;
const second = (cb) => {
setTimeout(function() {
return "I am second";
temp = cb();
}, 1000);
}
const third = () => {
return "I am third";
}
const solve = () => {
var f = first();
console.log(f);
var s = second(third);
setTimeout(()=>{
console.log(s);
console.log(temp);
},1100)
}
solve();
OUTPUT should be
I am first
I am second
I am third

You don't need that global temp variable, and your setTimeout callback in second doesn't really work. It should be cb("I am second");, just like where you'd usually call resolve("I am second"); in a new Promise. Then you can receive that value as the parameter of the callback function you're passing to second(…), which should then log it and continue with the remaining steps of the script.
const first = () => {
return "I am first";
}
const second = (cb) => {
setTimeout(function() {
cb("I am second");
}, 1000);
}
const third = () => {
return "I am third";
}
const solve = () => {
var f = first();
console.log(f);
second((s) => {
console.log(s);
const t = third();
console.log(t);
});
}
solve();
Notice this is not unlike your promise version if you were to use .then() instead of async/await syntax:
const solve = () => {
var f = first();
console.log(f);
second().then((s) => {
console.log(s);
var t = third();
console.log(t);
});
}

Related

async await issue promis

my function greetings works but when i try to return a promise to execute things once its done im getting nothing, what am i missing?
I have tried putting return resolve() as to make sure the function ends but still nothing, I can´t get the .then() to execute.
const greetingDivs = [firstDiv, secondDiv, thirdDiv, fourthDiv, fifthDiv]
let y = 0
function greetings() {
return new Promise((resolve, reject) => {
if (y == greetingDivs.length) {
// console.log('resolved')
resolve('done')
}
if (y != greetingDivs.length) {
setTimeout(() => {
let lastDiv = consoleOutput.appendChild(greetingDivs[y])
.scrollIntoView(false, { behavior: 'smooth' })
y++
greetings()
}, 300)
}
})
}
greetings().then(() => {
console.log('hello')
})
Your code only resolves one promise, while it creates 5. Notably, the first one, the one that greetings() returns, never resolves.
I would suggest promisifying setTimeout, so you have that logic once and for all. Then the looping can be done in an async function with a for loop and await:
const consoleOutput = document.body;
const [firstDiv, secondDiv, thirdDiv, fourthDiv, fifthDiv] = [
"Hello", "Welcome to this demo", "Hope it suits your case", "Test it", "and enjoy"].map(s => {
const div = document.createElement("div");
div.textContent = s;
return div;
});
const greetingDivs = [firstDiv, secondDiv, thirdDiv, fourthDiv, fifthDiv];
const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
async function greetings() {
for (let div of greetingDivs) {
consoleOutput.appendChild(div)
.scrollIntoView(false, { behavior: 'smooth' });
await delay(300);
}
}
greetings().then(() => {
console.log('hello');
});
See ES6 promise for loop for more ideas on how you can create such loops.

Promise ignoring simple syncronous operation

In a promise, I want to assign a value to the property of several objects created from a class (in a loop), but when executing the function and doing the .then(() => console.log(r)) thing, the r does was not modified to what the promise promised me it would.
Here:
function assignSentenceImageDescription () {
return new Promise((resolve, reject) =>
{
assigningWordsPartOFSpeech().then((r) => {
JSON.parse(r).sentences.forEach((sentence) => {
let adjectiveBeforeNoun = [];
let sentenceImageDescription = [];
sentence.words.forEach((wordInSentence) => {
try {
if (wordInSentence.partOfSpeech[0].wordtype === "n.") {
let imageDescription = adjectiveBeforeNoun.join('') + wordInSentence.partOfSpeech[0].word;
sentenceImageDescription.push(imageDescription)
adjectiveBeforeNoun = [];
} else if (wordInSentence.partOfSpeech[0].wordtype === "superl.") {
adjectiveBeforeNoun.push(wordInSentence.partOfSpeech[0].word + " ")
}
} catch (e) {
console.log("===NOT IN DICTIONARY===")
}
})
sentence.imageDescription = sentenceImageDescription;
}
)
resolve(r);
}
);
}
);
}
On the line
sentence.imageDescription = sentenceImageDescription;
I try to assign the image description of each of the sentences iterated over, but when I do
assignSentenceImageDescription().then(r => console.log(r));
the r object still does not have each of its sentences's imageDescription property modified to the value the array sentenceImageDescription has, which is what the assignSentenceImageDescription() function is intended to do.
Refactor your code as follows:
Note: you don't need a Promise constructor since assigningWordsPartOFSpeech returns a Promise that you can work with (and return)
Set sentences = JSON.parse(r).sentences;
Now you can iterate through sentences as you already do, then simply return sentences in the .then - and you're done
function assignSentenceImageDescription() {
return assigningWordsPartOFSpeech().then((r) => {
const data = JSON.parse(r);
data.sentences.forEach((sentence) => {
let adjectiveBeforeNoun = [];
let sentenceImageDescription = [];
sentence.words.forEach((wordInSentence) => {
try {
if (wordInSentence.partOfSpeech[0].wordtype === "n.") {
let imageDescription = adjectiveBeforeNoun.join('') + wordInSentence.partOfSpeech[0].word;
sentenceImageDescription.push(imageDescription)
adjectiveBeforeNoun = [];
} else if (wordInSentence.partOfSpeech[0].wordtype === "superl.") {
adjectiveBeforeNoun.push(wordInSentence.partOfSpeech[0].word + " ")
}
} catch (e) {
console.log("===NOT IN DICTIONARY===")
}
})
sentence.imageDescription = sentenceImageDescription;
});
return data;
});
}

JavaScript Throttle always returning function

I'm trying to understand JavaScript Throttling. I implemented a very basic throttle for the knowledge that I have so far.
const display = (msg) => {
return msg;
}
const throttleDisplay = (func, limit) => {
let flag = true;
return function() {
if(flag) {
func.apply(this, arguments);
flag = false;
setTimeout(() => flag = true, limit);
}
}
}
for(let i=1; i<=5; i++) {
setTimeout(() => {
const result = throttleDisplay(display("Hi"), 6000);
console.log(result)
}, i*1000);
}
My console.log is returning [Function] instead of the message Hi. Also, it is returning [Function] 5 times. Shouldn't it ignore the next call until the limit, 6000ms, has passed?
Thanks a lot!
Throttling works differently.
First, you should name your throttle function just throttle, as it is not specifically linked with display. Then, you should call this throttle to get a function that is specific to display. And only then you would use that secondary function in the actual use case you have for it, i.e. with the timer.
Here is your code corrected:
const throttle = (func, limit) => {
let flag = true;
return function() {
if(flag) {
func.apply(this, arguments);
flag = false;
setTimeout(() => flag = true, limit);
}
}
};
const throttleDisplay = throttle(() => console.log("Hi"), 6000);
for(let i=1; i<=10; i++) {
setTimeout(throttleDisplay, i*1000);
}

How to execute the second function firstly in chain functions in Javascript?

Question as below:
Create a function GoodMan
GoodMan("Tom")
output: I am Tom
GoodMan("Tom").rest(10).learn("computer")
output: I am Tom
//wait 10 seconds
Start learning after 10 seconds
Learning computer
GoodMan("Tom").restFirst(5).learn("english")
output:
//wait 5 seconds
Start learning after 5 seconds
I am Tom
Learning english
I have finished the first two questions. However, in the third question, how to execute the restFirst(5) function firstly in chain functions in Javascript?
Should I add a selector to determine whether GoodMan("Tom") execute.
Code shows below:
var GoodMan = function(str){
var callback_f = new Object;
str1 = "I am " + str;
console.log(str1);
callback_f.rest = function(num){
sleep(num * 1000);
console.log ("Start learning after " + num + " seconds");
return callback_f;
};
callback_f.learn = function(str){
str2 = "Leaning " + str;
console.log (str2);
};
return callback_f;
}
function sleep(ms) {
var unixtime_ms = new Date().getTime();
while(new Date().getTime() < unixtime_ms + ms) {}
}
GoodMan("Tom").rest(10).learn("computer");
How about having a queue of tasks?
function TaskQueue(tasks) {
return function createQueue(...args) {
const queue = [];
let running = false;
async function processQueue() {
if(running) return;
running = true;
// console.log(queue);
for(const { task, args } of queue) await task(...args);
running = false;
}
function addTask(task, priority, args) {
queue[priority ? "unshift" : "push"]({ task, args });
setTimeout(processQueue);
}
const instance = {};
for(const [key, priority, task] of tasks) {
instance[key] = function(...args) { addTask(task, priority, args); return this; };
}
if(instance.constructor) instance.constructor(...args);
return instance;
};
}
const GoodMan = TaskQueue([
["constructor", 0, (name) => console.log(`Hi, ${name}`)],
["rest", 0, (time) => new Promise(res => setTimeout(res, time * 1000))],
["restFirst", 1, (time) => new Promise(res => setTimeout(res, time * 1000))],
["learn", 0, subject => console.log(`Learning ${subject}`)]
]);
GoodMan("Tom").restFirst(5).learn("english")
You can try the code below:
const goodMan = (name) => {
return Promise.resolve(`I am ${name}`);
};
const restFirst = (time) => {
return Promise.resolve(`Start learning after ${time} seconds`);
};
const learn = (subject) => {
return Promise.resolve(`Learning ${subject}`);
};
const allTogether = (async () => {
const goodManOutput = await goodMan('Tom');
const restOutput = await restFirst(5);
const learnOutput = await learn('English');
return Promise.resolve(`${restOutput} ${goodManOutput} ${learnOutput}`);
});
allTogether().then(newOutput => {
console.log(newOutput);
});
Hope this helps.

How to return result of the nested function in javascript arrow function?

Can't figure out how to return result of the nested function in arrow function.
How to express this one (works fine):
var stopEating = (function() {
var loadedStomach = false;
return function() {
if(!loadedStomach){
loadedStomach = true;
console.log('Stop eating');
}};
})();
as an arrow function (doesn't work properly):
const stopEating = () => {
let loadedStomach = false;
return () => {
if(!loadedStomach) {
loadedStomach = true;
console.log('Its enough eating!');
}};
};
You need to call the function in order to get the results, thus, adding the parentheses at the end.
const stopEating = (() => {
let loadedStomach = false;
return () => {
if(!loadedStomach) {
loadedStomach = true;
console.log('Its enough eating!');
}
};
})();
Into the first example, you created Immediately Invoked Function Expression (IIFE).
It's a JavaScript function that runs as soon as it is defined. That's why you receive internal function, which prints "Stop Eating".
To realize this pattern you just need to wrap arrow function:
const stopEating = (() => {
let loadedStomach = false;
return () => {
if(!loadedStomach) {
loadedStomach = true;
console.log('Its enough eating!');
}
};
})();

Categories