Q.all()承诺不能正确解决延期承诺

时间:2013-06-20 16:16:29

标签: javascript promise q

我多次调用POST以便在服务器上创建对象。 POST包含在一个承诺中。我创建了一个promises数组并将其传递给Q.all但是当它被解析时,数组中的所有对象都具有相同的id,并且在服务器上只创建了一个对象。

这是我的代码

for (var i = txArray.length - 1; i >= 0; i--) {                
  txArray[i]._action = 'update';
  promises.push(newVertex(url));
};
return Q.all(promises).then(function(result){
  console.log(result);
});

function newVertex(url) {
    var deferred = Q.defer();
    var xhr;

    try {
        xhr = new_xhr();
    } catch (e) {
        deferred.reject(-1);
        return deferred.promise;
    }

    xhr.open('POST', url, true);
    xhr.onreadystatechange = function() {
        if (xhr.readyState === 4) {
            if (xhr.status === 200) {
                deferred.resolve(xhr.responseText);
            } else {
                deferred.reject(xhr);
            }
        }
    };

    xhr.send();
    return deferred.promise;
}

结果返回具有相同id的所有对象。不知道为什么?有没有人有任何建议。

2 个答案:

答案 0 :(得分:2)

我设法解决了这个问题。 POST有一个包含Content-Type:application / json的标题。因此,服务器期望将一些数据传递给它。传递一些json数据甚至'{}'解决了这个问题。

例如:

xhr.send('{}');

感谢每一位机构的反馈,这一切都有帮助。

答案 1 :(得分:-1)

如果xhr.open('POST', url, false)的一切正常,则会出现服务器无法正确处理多个同时请求的情况。在异步关闭的情况下,有效地强制要求处理请求。

理想的解决方案可能是修复服务器上的内容,但可能可以接受应用更好的客户端“顺序器”修复。

代码遵循一个相当熟悉的模式:

var promise = Q.defer().resolve().promise;//A ready-resolved seed promise.

//Now, instead of pushing promises onto an array, progressively build a .then() chain.
for (var i = txArray.length - 1; i >= 0; i--) {                
    txArray[i]._action = 'update';
    promise = promise.then(function() {
        return newVertex(url);
    });
};

//And add a terminal .then() to do whatever on completion of the sequence.
promise.then(function(result) {
    console.log(result);
});

这允许在xhr.open('POST', url, true);中使用newVertex()(即异步请求)。

我对最后.then()不太确定。你可能需要玩一些。

脚注

此修复程序可确保每个用户的请求都是顺序的。但是,服务器上的错误仍将存在。只有通过修复服务器上的任何错误,您才能确保来自两个或更多用户的并发请求不会产生问题;即可以发布重复的ID。这不一定会在测试期间发生,并且可能是潜在的错误,直到两个用户同时访问此特定资源时才会在未来的某个时间出现。

因此,只有一个用户可以同时访问资源(可能还有类似资源)时,上述修复才适用。为了安全起见,您需要在服务器上采取措施,以确保不会发生对资源的多个并发访问。毫无疑问,修复实际的bug几乎更容易 - 即确保不能多次发出相同的id。

因此,我重申上述解决方案仅可能可以接受。