javascript同步回调

javascript同步回调,javascript,synchronization,Javascript,Synchronization,我想看看是否有一种方法可以在消息上使用通用异步函数,如AJAX或WebWorker,并强制它同步运行 首先,我确实需要这种行为,我知道所有关于异步回调和返回的参数,但在这种情况下,我确实需要等待回调 如果没有通用的解决方案,我会选择一个纯粹在Worker.prototype.onmessage上工作的解决方案,因为这是这里的主要用例 我很确定答案是“那是不可能的”,但我想在投降前核实一下 我已经研究过promises和Generator,我不希望使用第三方库(我知道节点的光纤/未来) 一个潜在的

我想看看是否有一种方法可以在消息上使用通用异步函数,如AJAX或WebWorker,并强制它同步运行

首先,我确实需要这种行为,我知道所有关于异步回调和返回的参数,但在这种情况下,我确实需要等待回调

如果没有通用的解决方案,我会选择一个纯粹在
Worker.prototype.onmessage上工作的解决方案,因为这是这里的主要用例

我很确定答案是“那是不可能的”,但我想在投降前核实一下

我已经研究过promises和Generator,我不希望使用第三方库(我知道节点的光纤/未来)

一个潜在的用例:

function main(){
    worker = new Worker("someWorker.js")
    var result = worker.onmessage(function(event){
        return event.data;
    })
    //wait for worker.onmessage
    return result;
}

如果要保持函数的同步流,生成器函数是唯一可能的解决方案。您将发送所有异步任务,如
var result=yield new Worker('someWorker.js')

function*main
外部,您将使用
mainFn.next().value获得
worker
,然后附加
onmessage
监听器,该监听器将解析数据返回到
function*main
中,函数将恢复

完整的生成器示例如下所示

// write function as generator
function* main () {
    var result = yield new Worker("someWorker.js");
    return result;
}

// instantiate the generator and get the first yield value
var mainFn = main()
  , worker = mainFn.next().value

// set onmessage listener, which is callback, that sends data back to *main()
worker.onmessage = function(event) {
    mainFn.next(event.data);
}
这样,您的
main()
函数将保持与原始表单几乎相似的状态,因此您可以重用原始代码,但您需要编写周围的逻辑,这并不简单,而且无论如何都会使用回调


您似乎知道生成器是什么,而且它在各种浏览器中不受广泛支持,因此如果您想在网页上运行此代码,您需要ES6 transpiler。

相关jQuery问题:@Blazemonger,谢谢-但这只适用于ajax调用。绝对值得注意的是,只需启动辅助程序并将所有同步代码(取决于辅助程序结果)放入
onmessage
回调中即可。Promissions和generators只是更优雅地解决了同样的问题。@Vaclav,正如我提到的-我真的需要回报,我正在处理的项目不可能将所有代码重写为callback。这不起作用,因为随后对
mainFn.next()的调用
不要等待
工作者。onmessage
@ZackNewsham第一次调用
next()
main()
产生
工作者
,第二次调用
next()
传递
事件。数据
返回
main()
,用
事件替换
工作者
。数据
并继续
main()
。对
mainFn.next()的第二次调用
mainFn.next()
放在回调中,因此它确实会等待消息事件,但您的工作进程可能会返回多条消息。在这种情况下,您希望将消息累积到某个变量,然后在数据完成后,使用
mainFn.next将其传递回
main()
(completeData)
。我尝试使用一个普通的worker,可能是生成器在不同的浏览器中实现不同(我使用的是Chrome)。此外,我在Meteor中使用了它,Meteor在部署之前编译代码,因此可能会弄乱一些事情。我花了一段时间来思考它——它确实有效,但遗憾的是,它并没有比将代码编译成回调更干净——因为我不得不重新构造代码以使用生成器,我希望我可以简单地调用Generatorr、 然后返回最终结果。@Zack Newsham生成器的棘手之处在于,它们与外部世界是异步的。您可以或多或少地使用旧代码,但需要将其封装在相当复杂的处理逻辑中,这将解析所有生成的值以及最终的
re打开
,它的工作原理也类似于yield(注意,
结果
不是从中产生的),然后将此异步结果传递给其他生成器等,因此最终您可能会意识到,完全重写为回调并不是一个坏主意。