我如何从函数 foo 返回一个无同步请求的答案/结果?

我正在尝试从呼叫返回的值,以及将结果分配到函数内部的本地变量,并返回其中一个,但没有这些方式实际上返回答案 - 他们都返回不确定的或无论变量结果的初始值是什么。

一个不同步函数的例子,接受召回(使用 jQuery 的 ajax 函数):

function foo() {
    var result;

    $.ajax({
        url: '...',
        success: function(response) {
            result = response;
            // return response; // <- I tried that one as well
        }
    });

    return result; // It always returns `undefined`
}

使用 Node.js 的例子:

function foo() {
    var result;

    fs.readFile("path/to/file", function(err, data) {
        result = data;
        // return data; // <- I tried that one as well
    });

    return result; // It always returns `undefined`
}

例如,使用那时承诺的区块:

function foo() {
    var result;

    fetch(url).then(function(response) {
        result = response;
        // return response; // <- I tried that one as well
    });

    return result; // It always returns `undefined`
}

当前回答

下面是一些方法来处理无同步请求:

浏览器承诺对象 Q - 一个承诺图书馆为JavaScript A+ Promises.js jQuery 提交 XMLHttpRequest API 使用呼叫回复概念 - 作为实施在第一个答案

示例: jQuery 转移实施,以处理多个请求

應用程式 應用程式 應用程式 應用程式 應用程式 應用程式 應用程式 應用程式 應用程式 應用程式 應用程式 應用程式 應用程式 應用程式

其他回答

您可以使用此自定义图书馆(使用 Promise 编写)进行远程通话。

function $http(apiConfig) {
    return new Promise(function (resolve, reject) {
        var client = new XMLHttpRequest();
        client.open(apiConfig.method, apiConfig.url);
        client.send();
        client.onload = function () {
            if (this.status >= 200 && this.status < 300) {
                // Performs the function "resolve" when this.status is equal to 2xx.
                // Your logic here.
                resolve(this.response);
            }
            else {
                // Performs the function "reject" when this.status is different than 2xx.
                reject(this.statusText);
            }
        };
        client.onerror = function () {
            reject(this.statusText);
        };
    });
}

简单的使用例子:

$http({
    method: 'get',
    url: 'google.com'
}).then(function(response) {
    console.log(response);
}, function(error) {
    console.log(error)
});

另一种方法是从无同步函数中返回值,是通过将结果从无同步函数中存储的对象。

下面是相同的例子:

var async = require("async");

// This wires up result back to the caller
var result = {};
var asyncTasks = [];
asyncTasks.push(function(_callback){
    // some asynchronous operation
    $.ajax({
        url: '...',
        success: function(response) {
            result.response = response;
            _callback();
        }
    });
});

async.parallel(asyncTasks, function(){
    // result is available after performing asynchronous operation
    console.log(result)
    console.log('Done');
});

我正在使用结果对象来存储在无同步操作期间的值,这使得结果即使在无同步工作后也可用。

我使用这个方法很多,我会感兴趣知道这个方法有多好运作,在那里通过连续模块将结果传输回来。

让我们先看看森林,先看看树木。

这里有很多有很好的详细信息的答案,我不会重复任何一个。在JavaScript中编程的关键是首先有正确的整体执行的心理模式。

您的输入点(s)是作为一个事件的结果执行. 例如,一个脚本标签与代码被加载到浏览器. (因此,这就是为什么你可能需要担心页面的准备运行你的代码,如果它需要DOM元素首先建造,等等) 您的代码执行完成 - 尽管许多无同步的呼叫它做 - 没有执行任何你的呼叫回复

但你不應該使用任何戰術工具來解決一個問題,直到你很舒服的實際問題領域. 圖描這些依賴的地圖,知道什麼需要執行時。

我认为,无论使用哪种方法或机制,或者哪种框架(天角/反应)隐藏它,以下原则是:

在程序的流程中(思考代码或甚至最低水平:机器代码),数据可能不会在2秒后,3秒后回来,或者可能根本没有回来,所以没有常见的回来来使用,以便返回数据。

问题是:

我如何从无同步通话中返回答案?

可以被解释为:

如何让同步代码看起来同步?

解决方案将是避免呼叫,并使用一个组合的承诺和async/await。

我想举一个例子给一个Ajax请求。

(虽然它可以用JavaScript写作,但我宁愿用Python写作,并用Transcrypt编写到JavaScript。

首先,让我们启用 jQuery 使用,以便有 $ 作为 S 可用:

__pragma__ ('alias', 'S', '$')

设置一个函数返回承诺,在这种情况下,一个Ajax呼叫:

def read(url: str):
    deferred = S.Deferred()
    S.ajax({'type': "POST", 'url': url, 'data': { },
        'success': lambda d: deferred.resolve(d),
        'error': lambda e: deferred.reject(e)
    })
    return deferred.promise()

使用非同步代码,就好像它是同步的:

async def readALot():
    try:
        result1 = await read("url_1")
        result2 = await read("url_2")
    except Exception:
        console.warn("Reading a lot failed")