Return 来自异步或同步 JavaScript 请求的值

Return value from asynchronous OR synchronous JavaScript request

下面的函数先进行同步比较test == 0,如果通过则returns一些内容,如果不通过则进行异步请求。我的意图是稍后 return 一些其他内容,例如 "something from post callback",但我知道我做错了。不把Ajax请求改成同步,这样可以吗?

var value = function (test) {
    if (test == 0) {
        return 'value is zero ';
    } else {
        return $.post('/echo/html/', {
            html: 'false ',
            delay: .5
        }, function (r1) {
            console.log('r1', r1);
            return 'something from post callback';
        })
            .done(function (r2) {
            console.log('r2', r2);
            return 'something from done callback';
        });
    }
}(1);

console.log(value);

https://jsfiddle.net/o5kq8he6/2/

既然您已经 return 从 ajax 调用中获得承诺,那么从您的同步比较中,只是 return 已解决的承诺。然后,两个代码路径 return 都使用终端值解析,调用者可以使用相同的代码来处理结果,无论它在内部以何种方式工作。这是时同步时异步代码的常见设计模式。

var myFunc = function (test) {
    if (test == 0) {
        return $.Deferred().resolve('value is zero ');
    } else {
        return $.post('/echo/html/', {
            html: 'false ',
            delay: .5
        }).then(function (r2) {
            console.log('r2', r2);
            // this will be the return value of the promise
            return 'something from ajax finished';
        });
    }
};

myFunc(1).then(function(value) {
    // value is here either way
});

仅供参考,在您的 $.post() 中同时使用成功处理程序函数和 .done() 处理程序没有意义。如果你要 return 来自函数的承诺(这是我的建议),那么你应该只使用承诺处理程序,而不是成功回调。

您可能还需要了解,它对 return 来自 ajax 调用的成功处理程序的值没有任何用处。 return 值只是返回到 ajax 基础设施的异步内部,并且永远不会被任何东西使用。

全部异步:

var value = function (test, callback) {
    if (test == 0) {
        callback('value is zero ');
    } else {
        return $.post('/echo/html/', {
            html: 'false ',
            delay: .5
        }, function (r1) {
            console.log('r1', r1);
            callback('something from post callback');
        })
            .done(function (r2) {
            console.log('r2', r2);
            callback('something from done callback');
        });
    }
}(1, function(result) { console.log(result); } );

您可以模拟对其他人的异步调用,然后对所有人使用回调:

var value = function (test, callback) {
    if (test == 0) {
        callback('value is zero ');
    } else {
        return $.post('/echo/html/', {
            html: 'false ',
            delay: .5
        }, function (r1) {
            console.log('r1', r1);
            callback('something from post callback');
        })
            .done(function (r2) {
            console.log('r2', r2);
            callback('something from done callback');
        });
    }
}(1, myCallback);


function myCallback(result) {
   // here will the result be
}

您还可以使用 setTimeout 使同步调用实际表现为异步调用,以备不时之需。