Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/404.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ionic-framework/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 向非异步函数添加延迟函数_Javascript_Jquery_Asynchronous_Promise_Deferred - Fatal编程技术网

Javascript 向非异步函数添加延迟函数

Javascript 向非异步函数添加延迟函数,javascript,jquery,asynchronous,promise,deferred,Javascript,Jquery,Asynchronous,Promise,Deferred,我目前正在处理一个需要很长时间才能完成的函数,由于我无法使它更快完成,我将从其他脚本调用它,我想知道是否有一种方法可以在该函数中使用类似于承诺的东西 基本上 function longrunning(){ var def = new $.Deferred(); var result = {}; [DO STUFF THAT TAKES A WHILE] def.resolve(); return def.promise(result); } 我的基本问题是,因为所

我目前正在处理一个需要很长时间才能完成的函数,由于我无法使它更快完成,我将从其他脚本调用它,我想知道是否有一种方法可以在该函数中使用类似于承诺的东西

基本上

function longrunning(){
   var def = new $.Deferred();
   var result = {};
   [DO STUFF THAT TAKES A WHILE]
   def.resolve();
   return def.promise(result);
}
我的基本问题是,因为所有正在进行的事情都不是异步的,所以在所有事情完成之前,我的承诺不会被返回,所以稍后将调用longrunning的函数不会知道它是异步的。但当然,如果我在执行所有代码之前返回承诺,它将根本无法解决问题。我希望你明白我的意思。希望有人有主意。提前感谢,谢谢


问候Chris

将代码包装在
$中。即使在执行长时间运行的工作之前(例如,通过
setTimeout
),延迟的
(或本机承诺)将无法帮助您将承诺返回到调用代码。它所能做的就是让主UI线程在
longrunning
返回承诺后不久就卡住,而不是在调用
longrunning
本身时。所以,没有用。:-)

如果所讨论的函数没有操作DOM,或者如果它所做的操作可以从长期运行的逻辑中分离出来,那么这是一个很好的选择,可以移动到web工作线程(,),因此它根本不会在主UI线程上运行,而是在并行工作线程中运行,让UI自由地继续响应

longlunning
不会做实际的工作,它只是
postMessage
工作人员要求它做工作,然后在它收到工作完成的消息时解决你的承诺。大致如下(这只是一个代码草图,不是一个完全实现的解决方案):

(假设工作人员发回的是一个具有以下属性的对象:
id
[工作id]、
success
[标志],以及
result
[结果]或
error
[错误]。)

如您所见,我们已将工作发送给工人,并返回承诺;当工作者将工作发回时,侦听器解析延迟的工作

如果长时间运行的任务确实需要将DOM操作作为其工作的一部分,那么它可以将必要的信息发布回主脚本,让它在必要时代表自己执行这些操作。它的可行性自然取决于代码正在做什么


当然,如果您只需要在最新的浏览器上运行(或包含polyfill),您可以使用本机承诺,而不是jQuery的
$。Deferred


该函数的作用是什么?具体来说,它是否操纵DOM?不,您的函数不会更快,因为您使用的是承诺。唯一有帮助的方法是将长时间运行的东西分成小块,这样整个程序就可以保持反应性(同时花费更长的时间)。该函数基本上是对从另一个软件检索到的一个大json对象进行重新排序。DOM没有被操纵。代码不会更快,但在计算这些内容时,网站不会被冻结。谢谢。你说得对,我以前真的没有想到网络工作者
var pendingWork = {};
var workId = 0;
var worker = new Worker("path/to/web/worker.js");
worker.addEventListener("message", function(e) {
    // Worker has finished some work, resolve the Deferred
    var d = pendingWork[e.data.id];
    if (!d) {
        console.error("Got result for work ID " + e.data.id + " but no pending entry for it was found.");
    } else {
        if (e.data.success) {
            d.resolve(e.data.result);
        } else {
            d.reject(e.data.error);
        }
        delete pendingWork[e.data.id];
    }
});

function longrunning(info) {
    // Get an identifier for this work
    var id = ++workid;
    var d = pendingWork[id] = $.Deferred();
    worker.postMessage({id: id, info: info});
    return d.promise();
}
var pendingWork = {};
var workId = 0;
var worker = new Worker("path/to/web/worker.js");
worker.addEventListener("message", function(e) {
    // Worker has finished some work, resolve the Deferred
    var work = pendingWork[e.data.id];
    if (!work) {
        console.error("Got result for work ID " + e.data.id + " but no pending entry for it was found.");
    } else {
        if (e.data.success) {
            work.resolve(e.data.result);
        } else {
            work.reject(e.data.error);
        }
        delete pendingWork[e.data.id];
    }
});

function longrunning(info) {
    return new Promise(function(resolve, reject) {
        // Get an identifier for this work
        var id = ++workid;
        pendingWork[id] = {resolve: resolve, reject: reject};
        worker.postMessage({id: id, info: info});
    });
}