53

我正在与第三方 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,但它似乎针对的是异步设计模式。我想在我的代码中使用同步模式。

4

3 回答 3

38

这永远不会起作用,因为 JS VM 已经从那个 async_call 继续前进并返回了您尚未设置的值。

不要试图与自然和内置的语言行为作斗争。您应该使用回调技术或承诺。

function f(input, callback) {
    var value;

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

}

另一种选择是使用承诺,看看Q。这样你返回一个promise,然后给它附加一个then监听器,这与回调基本相同。当 promise 解决时, then 将触发。

于 2013-09-10T22:33:01.553 回答
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);
    } );
}
于 2013-09-10T22:31:13.687 回答
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/

于 2021-08-26T11:03:48.200 回答