javascript - 如何递归调用异步函数?

标签 javascript node.js asynchronous recursion

我已经定义了这个函数:

// retrieves zip of package manifest supplied

var retrieveZip = function(metadataClient, args, callback) {
  metadataClient.retrieve(args, function(err, result) {
    metadataClient.checkRetrieveStatus({id: result.result.id, includeZip: 'true'}, function(err, result) {
      if(result.result.done) {
        return callback(result);
      }
      // else check again!(how??)
    });
  });
}

retrieveZip(metadataClient, args, function(result) {
      console.log(result);
});

想法是客户端将尝试根据 args 中提供的元数据检索 zip 文件。 API 文档 (Salesforce SOAP API) 要求将检索方法结果中提供的 ID 传递到检查状态函数。

但是问题是这样的:

  1. 在第一次检查时,如果结果为“完成”,则只需将 checkRetreiveStatus 中的结果对象返回给回调(包含结果)

  2. 但是如果结果没有完成,我需要再次调用 checkRetrieveStatus...从 checkRetrieveStatus

  3. 天真的方法是将来自原始 checkRetrieveStatus 调用的参数传递给 checkRetrieveStatus 的新实例,但显然不可能知道这多少次将被调用。

听起来我需要一个递归解决方案?使用 while 循环会引入异步调用问题吗?

最佳答案

根据您的描述,听起来您只想调用 checkRetrieveStatus 直到它完成,不是 retrieve checkRetrieveStatus。对吗?

如果是这样,要做的事情就是将状态检查提取到您自己的可以递归调用自身的函数中,如下所示:

var checkStatus = function(metadataClient, id, callback) {
    metadataClient.checkRetrieveStatus({ id: id, includeZip: 'true' }, function(err, result) {
        if (result.result.done) {
            callback(result); 
        } else {
            checkStatus(metadataClient, id, callback);
        }
    });
};

var retrieveZip = function(metadataClient, args, callback) {
  metadataClient.retrieve(args, function(err, result) {
      checkStatus(metadataClient, result.result.id, callback);
  });
}

retrieveZip(metadataClient, args, function(result) {
      console.log(result);
});

如果您担心重复轮询结果时占用系统资源,您可以在检查之间加入延迟:

var checkStatus = function(metadataClient, id, callback) {
    metadataClient.checkRetrieveStatus({ id: id, includeZip: 'true' }, function(err, result) {
        if (result.result.done) {
            callback(result); 
        } else {
            setTimeout(function () {
                checkStatus(metadataClient, id, callback);
            }, 100);
        }
    });
};

var retrieveZip = function(metadataClient, args, callback) {
  metadataClient.retrieve(args, function(err, result) {
      checkStatus(metadataClient, result.result.id, callback);
  });
}

retrieveZip(metadataClient, args, function(result) {
    console.log(result);
});

关于javascript - 如何递归调用异步函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40330808/

相关文章:

javascript - 如何在Wordpress中使用RecordJs

memory - 如何查看cygwin中进程使用了​​多少内存?

java - 如何使用mongoDb java异步驱动程序插入到mongoDb集合后获取_id

javascript - 如何在 Bootstrap 中的页面加载时打开模态对话框

javascript - 显示/隐藏多个 Div

javascript - 查找矩阵中重复的最大值

node.js - 亚马逊 S3 服务器上的 Concat MP3/媒体音频文件

javascript - python对象和json对象有什么区别?

ajax - Promise 和 AJAX 有什么区别?

javascript - 了解去抖。 thunks 和赋值返回