等待异步任务完成

54

我正在与一个第三方JavaScript库交互,其中一些函数调用是异步的。但我没有将异步逻辑融入我的应用程序,而是编写了同步包装器来处理这些异步调用。我知道这是可怕的设计,但这只是一个演示项目,很可能会被完全重写。我需要展示这个概念给团队看,而不必担心性能问题。

这就是我想做的事情:

function sync_call(input) {
    var value;

    // Assume the async call always succeed
    async_call(input, function(result) {value = result;} );

    return value;
}

我尝试过 jQuery 的 deferred 和 promise,但似乎它们是针对异步设计模式。我想在我的代码中使用同步模式。


你不能为异步任务创建同步包装器。请使用延迟/承诺模式! - Bergi
2
可能是重复的问题:如何从异步调用中返回响应? - Liam
3个回答

39

这样做永远行不通,因为JS虚拟机已经从async_call中返回了值,而你还没有设置它。

不要试图与语言行为的自然和内置相抗衡。你应该使用回调技术或Promise。

function f(input, callback) {
    var value;

    // Assume the async call always succeed
    async_call(input, function(result) { callback(result) };

}
另一个选择是使用 Promise,请查看 Q。这样,您返回一个 Promise,并将 then 监听器附加到它上面,这基本上与回调相同。当 Promise 解决时,then 将触发。

好的,我没意识到。在C语言中可以实现(互斥锁),在C#中也可以(.NET内置支持)。那我会重新设计整个方案。我的团队最熟悉C#,所以如果我尽可能地编写与C#接近的代码,它被接受的机会会更大。 - Code Different
8
这看起来不对,并且实际上非常有趣,因为sync_call的签名与async_call的签名完全相同并且完全是多余的。如果sync_call接受回调函数,那么它将不再是同步的。它返回的值在哪里?在退出之前它并不会返回任何值。如果要使其成为同步的,必须在其返回/退出时返回值。 - Lzh
我尽可能少地改动了问题中的代码。到底是谁给函数命名为“sync”和“async”的呢?关键是用户正在使用回调进行异步调用,期望在原始函数的范围内解决它。我的非常简单和天真的代码向他的原始函数添加了一个回调,并在函数结束时停止了变量“value”的处理。 - bitoiu
由于使用与 OP 相同的函数名称受到了很多批评,我决定更改它。 - bitoiu

1

你可以尝试在回调函数内部调用一个函数,而不是在 sync_call() 中返回一个值。

function sync_call(input) {
    var value;

    // Assume the async call always succeed
    async_call(input, function(result) {
        value = result;
        use_value(value);
    } );
}

1
这不是一个正确的答案,因为回调函数没有在参数列表中定义。 - bitoiu
1
可以通过一些小的调整来使其可行,但实际上并没有太大区别于jQuery的Promise模式。无论如何,感谢您的回答。 - Code Different

0

这里是一个工作示例,演示如何实现:

function testAsync(){
    return new Promise((resolve,reject)=>{
        //here our function should be implemented 
        setTimeout(()=>{
            console.log("Hello from inside the testAsync function");
            resolve();
        ;} , 5000
        );
    });
}

async function callerFun(){
    console.log("Caller");
    await testAsync();
    console.log("After waiting");
}

callerFun();

输出:

Caller
Hello from inside the testAsync function
After waiting

为了使其更完整,应添加错误处理(处理reject()的情况)。
这里可以查看其他示例:https://www.delftstack.com/howto/javascript/javascript-wait-for-function-to-finish/

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接