【问题标题】:How to syncronize order of chained jQuery promised如何同步链式 jQuery 承诺的顺序
【发布时间】:2016-12-11 18:04:36
【问题描述】:

我将 3 个 ajax 请求链接到一个 RESTful 端点:

  1. PUT 一些数据(返回 {} 并确定)
  2. 获取我刚刚输入的数据
  3. 显示数据

我已经使用.then() 建立了一系列承诺。但请求不是按预期的顺序 (1,2,3) 发生,而是 (2,1) 并以 OPTIONSrequest 开头。

为什么它们没有按预期的顺序发生?

如何确保正确的顺序?

var _id = x;

function doReqs() {
  putData(_id, data)
    .then(getData(_id))
    .then(showData);
}

// returns empty object {}
function putData(id, data) {
  return $.ajax({
    method: 'PUT',
    url: http://xxx,
    contentType: 'application/json'
  });
}

// returns JSON {"data": {"xx": "xx}}
function getData(id) {
  return $.ajax({
    method: 'GET',
    url: http://xxx
  });
}

function showData(data) {
  console.log(data);
}

【问题讨论】:

  • 评论不用于扩展讨论;这个对话是moved to chat
  • 我如何访问聊天?

标签: javascript jquery ajax promise


【解决方案1】:

在这段代码中:

function doReqs() {
  putData(_id, data)
    .then(getData(_id))
    .then(showData);
}

.then(getData(_id)) 部分是错误的。有两个原因是错误的。

  1. .then() 应该被传递一个函数引用。当您传递getData(_id) 时,您将立即执行该函数并将该函数(它是一个jqXHR 对象)的返回值传递给.then()。这不是您应该传递给.then() 的内容。

  2. 因为您正在立即执行getData(_id),所以它不会在承诺链序列中正确执行。

请记住,任何时候您传递 func() 并在其后加上括号作为参数时,它都会立即执行该函数并将其返回值作为参数传递。由于上述原因,这不是您想要的 .then()

如果您试图控制传递给getData() 的内容,那么您可以确保从putData() 返回正确的内容,因为这就是将传递给getData() 的内容,或者您​​可以制作一个存根将传递正确内容的函数:

function doReqs() {
  putData(_id, data)
    .then(function() {
        return getData(_id);
    })
    .then(showData);
}

或者,你可以这样做:

function doReqs() {
  putData(_id, data)
    .then(getData.bind(null, _id))
    .then(showData);
}

或者,由于putData() 的解析值将作为参数传递给承诺链中的下一步(即getData),您可以这样做:

function putData(id, data) {
  return $.ajax({
    method: 'PUT',
    url: http://xxx,
    contentType: 'application/json'
  }).then(function() {
    // make sure putData passes the id to the next step in the chain
    return id;
  });
}

function doReqs(id) {
  putData(id, data)
    .then(getData)
    .then(showData);
}

这是一个实际链接的工作示例:

function delay(t, val) {
   return new Promise(function(resolve) {
       setTimeout(resolve.bind(null, val), t);
   });
}

function first(arg) {
    console.log("running first..., arg = ", arg);
    return delay(500, 10);
}

function second(arg) {
    console.log("running second..., arg = ", arg);
    return delay(100, 100);
}

function third(arg) {
    console.log("running third..., arg = ", arg);
}

first(1).then(second).then(third);

【讨论】:

  • 感谢您的详尽解释。尤其是关于在.then(xx) 中传递的方式和内容。我现在了解如何修复 ajax reqs 的执行顺序。我最终使用了您在 putData() 上的 .then() 中返回 id 的最后一条建议。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-23
  • 2015-02-04
  • 2021-02-27
相关资源
最近更新 更多