Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/40.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js 节点的异步问题_Node.js_Asynchronous - Fatal编程技术网

Node.js 节点的异步问题

Node.js 节点的异步问题,node.js,asynchronous,Node.js,Asynchronous,我有一个在节点应用程序中运行的函数,由于我不了解如何正确地编写异步代码,所以无法运行该函数。下面是一个函数,它接收电子邮件的配置文件。我想循环浏览每封电子邮件,查看我的数据库中是否存在该用户。如果他们这样做了,我想返回给定的回调并完全存在函数,而不做任何其他事情。如果找不到该用户,我将根据概要文件中给出的信息创建一个新用户,然后返回与新创建的用户相同的回调。到目前为止,该函数按预期工作,只是它创建了一个新用户,即使在我的数据库中已经找到了一个用户。(上面定义了'User'变量,并具有'creat

我有一个在节点应用程序中运行的函数,由于我不了解如何正确地编写异步代码,所以无法运行该函数。下面是一个函数,它接收电子邮件的配置文件。我想循环浏览每封电子邮件,查看我的数据库中是否存在该用户。如果他们这样做了,我想返回给定的回调并完全存在函数,而不做任何其他事情。如果找不到该用户,我将根据概要文件中给出的信息创建一个新用户,然后返回与新创建的用户相同的回调。到目前为止,该函数按预期工作,只是它创建了一个新用户,即使在我的数据库中已经找到了一个用户。(上面定义了'User'变量,并具有'create'函数。此外,如果可能的话,我希望避免使用'async'节点模块)


这有什么问题吗

function processProfile(profile, callback) {
    var existingUser;
    var index = 0;

    function processNextEmail() {
        if(index >= profile.emails.size()) return; //When we've popped nothing exit
        var email = profile.emails[index++];
        console.log("Searching for user with this email:" + email.value);
        existingUser = findUserByEmail(email.value);
        if (existingUser) {
            console.log("Found the existing user");
            callback(null, existingUser);
            processEmail();//recursive call to prcess the next email
        } else {
            console.log("Creating new user");
        var newUser = {
            id: profile.id,
            firstName: profile.name.givenName,
            lastName: profile.name.familyName,
            email: profile.emails[0].value
        };
        user.create(newUser, provider, function(err, user) {
            if (err) throw err;
            callback(null, user);
            processNextEmail();//recursive call to process the next email after creating the user and adding it to the database.
        });
        }
    }

    processNextEmail();
}
如果需要递归逻辑来不删除电子邮件,可以在processProfile()闭包的范围内进行一个简单的修改,包括一个indice

还要注意,return callback()行实际上什么都不做。从异步执行的函数返回是浪费时间。只要调用回调函数,然后如果愿意,可以调用空返回函数跳过函数的其余部分,但这是不必要的,除非返回影响逻辑流

编辑:事实证明,这个例子太简单了,不太有趣。我用下面的代码作为一些在工作中难以掌握异步代码的人的示例。我认为在node中使用同步代码可以用来收集配置数据。让我们假设配置存储在一个文件中,然后从该文件中获取文件名,并从另一个文件中收集另一层配置数据。我们可以通过两种方式来实现这一点,使用readFileSyn,或者使用readFile。异步版本很棘手,因为我们需要等待第一步完成,因为我们必须从第一个文件中获取文件名,以便知道第二个文件存储在哪里。下面是同步解决方案和异步解决方案的代码

//The synchronous way
function useConfigurationData(configData) {
    dosomethinginterestingwith(configData);
}

function getConfigurationData(fileName) {
    var fileName2 = fs.readFileSync(fileName);
    var configurationData = fs.readFileSync(fileName2);
    return configurationData;
}

var fileData = getConfigurationData('someFile');
useConfigurationData(fileData);


//The equivalent async way
function getConfigurationData(fileName, useConfigDataCallBack) {
    fs.readFile(fileName, getConfigDataStepTwo);

    function getConfigDataStepTwo(err, fileName2) {
        fs.readFile(fileName2, getConfigDataStepThree);
    }

    function getConfigDataStepThree(err, fileData) {
        useConfigDataCallBack(fileData);
    }
}

getConfigurationData('someFile', useConfigurationData);
请注意,我们提供给getConfigurationData的回调是最后一步。我们也可以只依赖全局定义的getConfigurationData函数,但将其作为回调传递是更好的方式


我喜欢这种语法,是第二个getConfigurationData函数以非常同步的顺序读取的代码。但是,如果您遵循逻辑流程,那么所有这些都是异步运行的。它易于阅读并遵循节点异步I/O模型。对于配置数据,我认为同步选项是可以接受的,但这仍然是如何从异步回调中获取同步行为和语法(ish)的一个很好的演示。

是的,不幸的是,这将为数据库中尚未包含的每封电子邮件创建一个用户。每个配置文件可能有多封电子邮件,但只有一个用户。我的目的是查看配置文件中是否有任何电子邮件在我的数据库中,如果没有,那么我只想创建一个用户,列表中有第一封电子邮件。forEach在循环本身中阻塞。因此,每个元素都保证按顺序处理。将您创建的用户添加到数据库中,以便可以通过连续的电子邮件找到该用户。如果用户创建过程是异步的,则可以递归地执行此操作,而不是使用forEach。我将demo.user.create实际将用户添加到数据库中。此功能用于passport模块,以便通过facebook登录。我可以看到,每次我通过facebook登录时,它都会在我的数据库中创建一个具有完全相同信息的新用户。对,这就是我修改它的原因,我看到该user.create接受回调,因此可能是异步的。。。我现在举的例子应该有用。
//The synchronous way
function useConfigurationData(configData) {
    dosomethinginterestingwith(configData);
}

function getConfigurationData(fileName) {
    var fileName2 = fs.readFileSync(fileName);
    var configurationData = fs.readFileSync(fileName2);
    return configurationData;
}

var fileData = getConfigurationData('someFile');
useConfigurationData(fileData);


//The equivalent async way
function getConfigurationData(fileName, useConfigDataCallBack) {
    fs.readFile(fileName, getConfigDataStepTwo);

    function getConfigDataStepTwo(err, fileName2) {
        fs.readFile(fileName2, getConfigDataStepThree);
    }

    function getConfigDataStepThree(err, fileData) {
        useConfigDataCallBack(fileData);
    }
}

getConfigurationData('someFile', useConfigurationData);