【问题标题】:Wrapping async functions with callbacks within用回调包装异步函数
【发布时间】:2021-06-26 20:33:12
【问题描述】:

我需要在一个新函数中顺序调用两个异步函数。这两个函数都使用回调来执行异步操作。

当我一个一个地调用我的函数时,我面临的问题是,据我所知,它们是同步调用的,第二个函数不等待第一个函数执行

如何包装它们以按顺序执行?

我拥有的代码:

let firstFunction = (data, callback) => {

    DBCallingFirst
    .asyncMethodFirst(resultObj, (err, result) => {
      if (err) return callback(err);
      // Some code
    });
}

let secondFunction = (data, callback) => {

    DBCallingSecond
    .asyncMethodSecond(resultObj, (err, result) => {
      if (err) return callback(err);

      // Some code
    });
}

let newFunction = (data, callback) => {

    firstFunction(data, callback);
    
    secondFunction(data, callback);
}

感谢您的关注!

【问题讨论】:

    标签: javascript asynchronous callback


    【解决方案1】:

    如果您能够使用 Promise 或 async/await,则可以使这变得更简洁。实际上,您可以在第一个回调中执行第二个 db 操作 - 这样可以保证第一个在调用第二个之前完成

        let firstFunction = async (data, callback) => {
    
        DBCallingFirst
        .asyncMethodFirst(resultObj, (err, result) => {
          if (err) return callback(err);
          DBCallingSecond
            .asyncMethodSecond(resultObj, (err, result) => {
              if (err) return callback(err);
              // Some code
            });
        });
    }
    

    编辑:有了 Promise,你可以像这样构造它:

    let firstFunction = (data) => {
      return new Promise(() => {
        DBCallingFirst
          .asyncMethodFirst(data, (err, result) => {
            if (err) {
              return Promise.reject();
            }
            return Promise.resolve(result);
          });
      });
    }
    
    let secondFunction = (data) => {
      return new Promise(() => {
        DBCallingSecond
        .asyncMethodSecond(data, (err, result) => {
          if (err) {
            return Promise.reject();
          }
          return Promise.resolve(result);
        });
      });
    }
    
    let newFunction = (data, callback) => {
    
      firstFunction(data).then((result1) => {
        secondFunction(data).then(result2) {
    
        }).catch(err2) {
          console.error(err2);
        });
      }.catch((err1) => {
        console.error(err1);
      });
    }
    

    【讨论】:

    • 我需要坚持清晰的结构。我只调用第一个函数,然后调用第二个函数,所有这些操作都在新函数中执行我可以包装这两个函数以返回新的 Promise,然后按顺序调用它们吗?如果可以,我应该怎么做?
    • 承诺更新
    • 感谢您的帮助!
    【解决方案2】:

    从这两个函数返回 Promise 并像这样等待它们

    const firstFunction = (data) => {
      return new Promise((resolve, reject) => {
        DBCallingFirst.asyncMethodFirst(data, (err, result) => {
           if(err) reject(err);
           resolve(result);
        })
      })
    }
    
        const secondFunction = (data) => {
          return new Promise((resolve, reject) => {
            DBCallingSecond.asyncMethodSecond(data, (err, result) => {
               if(err) reject(err);
               resolve(result);
             })
          })
        }
    

    现在您可以使用 await 顺序调用它们两个

    const newFunction = async (data) => { // note the async part in function definition
      try {
         const result1 = await firstFunction(data);
         const result2 = await secondFunction(data); // this will be executed only after firstFunction resolves/rejects;
      } catch (err) { 
        console.log('Error from the function', error) // promise rejection will be caught here
      } 
       
    }
    

    【讨论】:

    • 这个很干净,我喜欢这个解决方案!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-16
    • 1970-01-01
    • 2019-01-27
    • 2015-01-22
    • 2018-04-06
    • 2020-12-14
    相关资源
    最近更新 更多