【问题标题】:How to fetch value from Promise object after promise has been resolved解决承诺后如何从 Promise 对象中获取值
【发布时间】:2015-02-17 11:10:17
【问题描述】:

请注意这是一个人为的例子。

    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

问题

我无法弄清楚在shortAfterLongFunc 完成后如何返回任何类型的对象/函数以进行进一步的下游处理。我可以从shortAfterLongFunc 获得console.log,但这不是我在这里需要的。 Fiddle Here

感谢收看!

更新:

好吧,只是为了让我的问题稍微好一点……这是我正在研究的一个简单用例:

$.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() 可以说将 Array 的每个元素处理为小写。但是,假设此处理需要很长时间并且是异步的(想想 setTimeout).. 因此承诺确保每个元素的同步操作......但是在使用承诺时我发现自己无法返回转换后的值

【问题讨论】:

    标签: javascript jquery promise jquery-deferred


    【解决方案1】:

    只需链接另一个 then 调用,因为 shortAfterLongFunc 返回新的承诺,您可以进一步使用它:

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

    演示:http://jsfiddle.net/ebt4pxxa/2/

    【讨论】:

    • 我怎样才能从promise 中得到data 的值...假设我有一个函数someFunc 包装代码:function someFunc(){longFunc().then(shortAfterLongFunc).then(function(data) { console.log('all is complted', data); }); // I want to return data when someone calls someFunc()}
    • 你不能从这样的函数返回数据。这不是同步代码,所以你不能只从它返回。您应该返回 Promise 对象并使用它。 function someFunc() { return longFunc().then(...); }; var pr = someFunc(); pr.then(function(data) { console.log(data) });。返回承诺,将承诺分配给变量,传递并使用其then 方法来访问已解析的数据。
    • 点击运行时小提琴不产生任何输出。
    • @DavidSpector 你检查控制台了吗?
    • 我点击了运行,输出的白色矩形保持白色。如果你正在创建一个小提琴,它应该做一些显而易见的事情。我不认为 Fiddle 模拟日志或调试器或网络工具。实际上,控制台日志是 WebExtensions 的另一个对我不起作用的区域。在我的后台和前台代码中,console.log() 很少生成任何输出。为什么?它是异步的并且需要暂停吗?我对此表示怀疑。
    【解决方案2】:

    有个窍门,定义一个数组或对象,然后在里面赋值:

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

    这里我使用 setTimeout 作为等待来防止在承诺执行完成之前打印结果。 这是没有 setTimeout 的 Codepen 示例:https://codepen.io/MNSY22/pen/NWPdvxd

    【讨论】:

    • 不正确..如果您在 callImport() 之后没有 setTimeout 的 console.log(Result) 结果仍将显示旧值。
    • 它对我来说是正确的,它的示例代码我不想让它太复杂,你需要使用同步等待,比如添加 async (load)=>{await import('..,
    • Async await 是 JavaScript 糖,它使异步代码看起来是同步的。这并不意味着你的代码已经自动同步了。
    • 超时是无法处理异步输入的。如果您的请求花费的时间比您的时间长,那么这将失败
    • @JESii 我知道超时不是处理方式,我是否在评论中解释了我作为示例放置的示例来展示这个技巧是如何工作的,您可以根据需要实施,这是 Codepen 示例向您展示它工作没有超时,我希望能找到你的答案:codepen.io/MNSY22/pen/NWPdvxd
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-24
    • 2022-12-17
    • 2020-11-02
    • 2018-05-16
    • 2017-07-18
    • 2018-10-08
    • 2020-04-19
    相关资源
    最近更新 更多