【问题标题】:nodejs- Best method to perform multiple async calls inside a function?nodejs- 在函数内执行多个异步调用的最佳方法?
【发布时间】:2018-08-09 11:48:02
【问题描述】:

我正在使用 Express JS (Express 4) 框架创建一个 API。我对 NodeJS 很陌生,所以我想知道在同一个函数中执行多个异步调用的最佳方法。

对于这个例子,我的登录控制器中有一个名为 Login 的函数。在这个函数中,假设我要进行相当多的异步调用来验证用户、保存登录信息和类似的功能。

但是对于某些异步调用,要处理的数据应该从之前的异步调用中获取(它们是依赖函数),而有些函数不是这样的。

现在,我就是这样打电话的。

exports.login = function (req, res) {

    var user = {
      email: 'fakeemail@id.com',
      password: 'password'
    };
    //Async call 1
    Login.authUser(user, function (err1, rows1) {
        var user_id = rows1[0].id;

        //Async call 2 (depends on async call 1 for user_id)
        Login.fetchUserDetails(user_id, function (err2, rows2) {

            //Async call 3
            Login.updateLoginInfo(param3, function (err3, rows3) {

                //Some functionality occurs here then async call 4 happens

                //Async call 4
                Login.someOtherFunctionality(param4, function (err4, rows4) {
                    //return response to user
                    res.json({
                        success: true
                    });
                });

            });
        });

    });
};

现在所有这些异步调用都是嵌套的。有没有其他方法可以做到这一点?

P.S:我没有在这个例子中添加错误处理

【问题讨论】:

    标签: node.js express asynchronous node-async


    【解决方案1】:

    您也可以使用promise。它会让你的语法更漂亮。你的代码看起来像

    Login.authUser(user).
    then(fetchUser).
    then(updateLoginInfo).
    then(someOtherFunctionality).
    catch(function(error){
    //log your error or whatever
    });
    

    【讨论】:

    【解决方案2】:

    您可以按照 Shahzeb 的建议使用 Promise

    Promises 是将来会解析的对象(异步)。一旦Promise 完成,它要么解决要么拒绝。所有已解决的承诺都是then ed,而那些被拒绝的是catch ed

    伪代码

    let myPromise = function() {
       return new Promise(function(resolve, reject) {
        resolve('foo');
      });
    };
    
    myPromise().then( (v) => {
      console.log(v);
    })
    

    【讨论】:

      【解决方案3】:

      使用承诺链

      new Promise(function(resolve, reject) {
      
        setTimeout(() => resolve(1), 1000); // (*)
      
      }).then(function(result) { // (**)
      
        alert(result); // 1
        return result * 2;
      
      }).then(function(result) { // (***)
      
        alert(result); // 2
        return result * 2;
      
      }).then(function(result) {
      
        alert(result); // 4
        return result * 2;
      
      });
      更多详情请参阅Promise Chainingchain promises in javascript

      【讨论】:

        【解决方案4】:

        使用async/await(需要Node.js v7.6) 这个策略也使用了 Promise。在我看来,它提高了可读性,因为您将每个单独的 Promise 调用重构为单独的方法。

        Codepen

        // mock async calls
        const authUser = user => Promise.resolve([{ id: 1 }]); // returns users id
        const fetchUserDetails = user_id => Promise.resolve({ name: 'Fred', age: '10000' }); // returns users details
        const updateLoginInfo = param3 => Promise.resolve({ status: 'success' }); // returns success?
        const someOtherFunctionality = param3 => Promise.resolve({ field: 'value' }); // returns something
        
        // all async functions return a promise
        const login = async (/*req, res*/) => {
        
          // User object
          const user = {
            email: 'fakeemail@id.com',
            password: 'password'
          };
        
          // Async call 1
          console.log(`Authorizing user...`);
          const rows1 = await authUser(user);
          const user_id = rows1[0].id;
          console.log(`User ${user_id} authorized.`);
        
          // Async call 2 (depends on async call 1 for user_id)
          console.log(`Fetching user detail...`);
          const rows2 = await fetchUserDetails(user_id);
          console.log(`User Detail was fetched: ${JSON.stringify(rows2)}`);
        
          // Async call 3
          console.log(`Updating login info...`);
          const param3 = `something`;
          const rows3 = await updateLoginInfo(param3);
          console.log(`Login info was successful: ${JSON.stringify(rows3)}`);
        
          // Some functionality occurs here then async call 4 happens
          console.log(`\nDoing stuff after async call 3, but before async call 4....\n`);
        
          // Async call 4
          console.log(`Async call 4...`);
          const param4 = `something`;
          const rows4 =  await someOtherFunctionality(param4);
          console.log(`END OF LOGIN FUNCTION`);
        
          return 'returned value';
        }
        
        // run the async function
        login()
          .then(result => {
            // respond
            // res.json({ success: true });
            console.log(`Promise value: ${result}`);
            console.log(`Response: { success: true }`);
          })
          .catch(err => {
            console.log(err);
          })
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-07-16
          • 2016-01-31
          • 2018-09-11
          • 2018-07-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-10-15
          相关资源
          最近更新 更多