11

Please note This is a contrived example.

    function longFunc(){
        var deferred = $.Deferred();

        setTimeout(function(){
            console.log("long func completed");
            deferred.resolve("hello");
        }, 3000);

        return deferred.promise();
    }

    function shortAfterLongFunc(x){
        console.log('short func completed with value: ' + x);
        return {
            a: x
        };
    }

processFurther(longFunc().then(shortAfterLongFunc)); // send the array for further processing

Problem

I am unable to figure out how to return any kind of object/function for further downstream processing after shortAfterLongFunc completes. I can console.log from shortAfterLongFunc but that's not what i require here. Fiddle Here

Thanks for looking!

UPDATE:

Okay just to make my question slightly better...this is a simple use case I am looking at:

$.map(['H','E','L','L', 'O'], somefunc). // for each item in array apply somefunc function

function somefunc(x){ // gets called for each value 'H', 'E' etc. in the array by $.map()
    var longfunc = function(y){
        var deferred = $.Deferred();

        setTimeout(function(){
            console.log("long func completed");
            deferred.resolve(y.toLocaleLowerCase());
        }, 3000);

        return deferred.promise();
    };

    var shortAfterLongFunc = function(x){
        console.log('short func completed with value: ' + x);
        return x;
    }

    // What should I do here
    return longFunc(x).then(shortAfterLongFunc); // must return lower case char to the caller of someFunc

}

somefunc() lets say processes each element of Array to lower case. However, assume this processing takes a long time and async (think setTimeout).. hence a promise to ensure synchronous operation for each element...but on using promise I find myself not able return the transformed value

Vikram
  • 4,162
  • 8
  • 43
  • 65

2 Answers2

10

Just chain another then call, since shortAfterLongFunc returns new promise you can further work with it:

longFunc().then(shortAfterLongFunc).then(function(data) {
    console.log('all is complted', data);
});

Demo: http://jsfiddle.net/ebt4pxxa/2/

dfsq
  • 191,768
  • 25
  • 236
  • 258
  • 1
    How can I get the value `data` out of `promise`...say I have a function `someFunc` wrapping the code: `function someFunc(){longFunc().then(shortAfterLongFunc).then(function(data) { console.log('all is complted', data); }); // I want to return data when someone calls someFunc()}` – Vikram Dec 18 '14 at 16:06
  • 5
    You can't return data from such function. This is not synchronous code, so you can't just return from it. You should return promise object and use it. `function someFunc() { return longFunc().then(...); }; var pr = someFunc(); pr.then(function(data) { console.log(data) });`. Return promise, assign promise to variable, pass around and use its `then` methods to access resolved data. – dfsq Dec 18 '14 at 16:11
  • The fiddle doesn't produce any output when Run is clicked. – David Spector Dec 20 '18 at 13:57
  • 1
    @DavidSpector Did you check console? – dfsq Dec 21 '18 at 09:00
  • I clicked Run and the white rectangle of output stayed white. If you are creating a fiddle, it should do something obvious. I don't think Fiddle simulates the log or debugger or network tools. Actually, the console log is another area of WebExtensions that doesn't work for me. In my background and foreground code, console.log() very rarely generates any output. Why? Is it asynchronous and requires a pause? I doubt it. – David Spector Dec 21 '18 at 13:07
-1

There is a trick, define an array or object and value it in then:

    let Result=[];
    let callImport = (load)=>{ 
        import('./component.js').
            then((Module)=>{
                load[0] = Module;
            });};
    callImport(Result);
    setTimeout(()=> console.log(Result[0]),10);

Here i used setTimeout as await to prevent print Result before promise execution finish. Here is Codepen sample without setTimeout : https://codepen.io/MNSY22/pen/NWPdvxd

Mohsen
  • 4,049
  • 1
  • 31
  • 31
  • Not true .. if you console.log(Result) without setTimeout after callImport() Result will still show old value. – Vikram Nov 08 '19 at 16:00
  • Its true and work for me, its sample code i didnt want make it too complex it, you need use sync await, like add async (load)=>{await import('.., – Mohsen Nov 08 '19 at 16:51
  • Async await is JavaScript sugar that makes asynchronous code look synchronous. It does not mean your code has become synchronous automatically. – Vikram Nov 08 '19 at 17:15
  • Timeut is no way to handle asynchronous input. If your request takes longer than your time, then this will fail – JESii Dec 18 '19 at 02:04
  • 1
    @JESii i know timeout is not way to handle, is i explain in comment i put as sample to show how this trick works and you can implement as you need, here is Codepen example to show you its work without timeout, i hope find your answer : https://codepen.io/MNSY22/pen/NWPdvxd – Mohsen Dec 18 '19 at 11:41