在 NodeJS Bluebird 中'success'响应时解决或拒绝承诺"request/ajax "



我对使用bluebird的承诺很陌生。当状态响应从api更改为"成功"时,我试图解决一个承诺。下面是我的代码:

exports.getdata(taskCreation, headers) {
  var deferred = Promise.pending();
  var headers = {
    "Authorization": "Secret xxxxxxxxxxxxxxxxx"
  };
  while (true) {
    request.get({
      url: "https://dragon.stupeflix.com/v2/status",
      qs: {
        tasks: taskCreation[0]["key"]
      },
      headers: headers,
      json: true
    }, function (error, httpObj, taskStatusAndResult) {
      if (!error && httpObj.statusCode == 200) {
        console.log(taskStatusAndResult[0]["status"]); //contains either "queued", "executing", "success", or "error"
        if (taskStatusAndResult[0]["status"] == "success")
          deferred.resolve(taskStatusAndResult);
      } else {
        deferred.reject(error);
      }
    })
  }
        return deferred.promise;
}

api需要几秒钟来处理视频,生成videourl并显示"成功"状态。在此之前,我想反复调用api,并解决承诺只有当状态是"成功"。我的代码与无限while循环不工作。关于如何以最好的方式实现这一要求,有什么建议吗?

您应该始终在尽可能低的级别承诺,以便您可以对其他所有内容使用承诺。

function makeRequest() {
  return new Promise(function(resolve, reject) {
    request.get({
      url: "https://dragon.stupeflix.com/v2/status",
      qs: {
        tasks: taskCreation[0]["key"]
      },
      headers: {
        "Authorization": "Secret xxxxxxxxxxxxxxxxx"
      },
      json: true
    }, function (error, httpObj, taskStatusAndResult) {
      if (error) reject(error);
      else if (httpObj.statusCode != 200) reject(httpObj); // or so
      else resolve(taskStatusAndResult);
    });
  });
}

现在我们可以使用承诺语法来编码你的应用程序用例,在这种情况下,一个递归算法,重新尝试请求,直到它得到一个success:

function getData(taskCreation, headers) {
  return makeRequest(taskCreation, headers).then(function(taskStatusAndResult) {
    if (taskStatusAndResult[0]["status"] == "success")
      return taskStatusAndResult;
    else
      return getData(taskCreation, headers); // do it again
  });
}
exports.getdata = getData;

不能在异步操作中使用while()循环。它会在任何一个API调用完成之前启动无数个API调用。相反,你必须对事情进行排序。进行一次API调用。得到结果后,在结果处理程序中决定下一步要做什么。

另外,您没有对您创建的承诺做任何事情,所以我决定从您的函数返回承诺。

并且,你的exports.getData声明不是一个正确的函数声明。


这里有一个想法,你返回一个承诺,如果你最终找到"成功"状态,承诺将被解决,如果出现错误条件,承诺将被拒绝。

实现以下逻辑:

  1. 调用API。当你得到响应时,做以下四件事之一:
  2. 如果响应是错误的,用该错误拒绝承诺
  3. 如果响应成功,用结果
  4. 解析承诺
  5. 如果响应不是错误,但尚未成功,并且您已超过重试的最大次数,则使用最大重试次数拒绝
  6. 如果响应不是错误,但还没有成功,并且没有超过重试的最大次数,那么再试一次
  7. 从函数返回一个承诺,这样调用者就可以在承诺上使用.then()来从操作中获得结果或错误

代码如下:

exports.getdata = function (taskCreation, headers) {
    var headers = {"Authorization": "Secret xxxxxxxxxxxxxxxxx"};
    var cntr = 0;
    var maxRetries = 20;
    return new Promise(function (resolve, reject) {
        function next() {
            ++cntr;
            request.get({
                url: "https://dragon.stupeflix.com/v2/status",
                qs: {tasks: taskCreation[0]["key"]},
                headers: headers,
                json: true
            }, function (error, httpObj, taskStatusAndResult) {
                if (!error && httpObj.statusCode == 200) {
                    console.log(taskStatusAndResult[0]["status"]); //contains either "queued", "executing", "success", or "error"
                    if (taskStatusAndResult[0]["status"] === "success") {
                        // found success to resolve the promise
                        resolve(taskStatusAndResult);
                    } else {
                        // if not "success" yet, then try again
                        if (cntr > maxRetries) {
                            reject(new Error("max retries exceeded"));
                        } else {
                            // try again
                            next();
                        }
                    }
                } else {
                    // got some kind of error here, so stop further processing
                    reject(error);
                }
            })
        }
        // start the first request
        next();
    });
}

最新更新