1

我已经看到了很多关于此的问题,但似乎没有什么可以为我的案例提供正确的答案。我也看到了使用的答案,.pipe但我正在寻找使用的答案.then

好的。我需要进行 3 次 ajax 调用,比如说一个允许多个帐户的投票应用程序。为了使帐户可以投票,需要完成的过程如下。

  1. 登录
  2. 选择选项
  3. 提交
  4. 注销(只需清除 cookie,无需发布)。

假设我有 2 个帐户:

var accts = [{user: "acct1", pswd: "1234"},{user: "acct2", pswd: "4321"}];

现在我需要使用 jquery 遍历这些帐户$.each

$.each(accts, function(key,value){

});

我了解到 using$.Deferred可以完美地做到这一点,但要正确实施。

我想要的是

--------loop1--------
login
select
vote
--------loop2--------
login
select
vote
All Done!.

但是发生的事情是(当我尝试console.log了解正在发生的事情时)全部完成!登录(2) 选择(2) 投票(2)

所以这是我的代码:

$.each(data, function(k, v) {
    promise.then(function() {
        return $.post(loginURL, {user: v.username, passwrd: v.password});
    }).then(function(html) {
        if (data > 0) {
            console.log('Logged In!');
            return $.post(pollURL + 'select.php', {id: 143});
        } else {
            console.log('Login Failed.');
            return false;
        }
    }).then(function(data) {
        if (data === 'selected') {
            console.log('Already have a selection.');
            return false;
        } else {
            return $.post(pollURL + 'submit.php');
        }
    }).then(function(data){
         if(data > 1) {
             Console.log('Successfully Voted.');
         } else {
           // if possible return to the login?
         }
    });
});

promise.done(function() {
    console.log('All Done. Logged out.');
});

我究竟做错了什么?。

4

2 回答 2

6

啊,这类似于我挣扎了一段时间的过程。我的解决方案是.apply在 jQuery 上使用.when来处理“未知”数量的 ajax 调用并全部解决。

鉴于您的情况,这并不是您所需要的,但它可能会为您提供一些解决问题的想法。我试图在你想要做的事情的背景下陈述我的过程,所以

var ajaxArgs = [{id: 1, password: "qwerty"}, {id: 2, password: "zxcvb"}];

function doLogin(id, pass) {
  return $.post("ws/path/here", {id: id, pass: pass});
}

var logins = $.when.apply(null, ajaxArgs.map(function(argSet) { 
  return doLogin(argSet.id, argSet.password); 
});

logins.done(function(){
    var logins = [].concat(arguments);
    logins.forEach(function(login) {
       //do Vote
       //do Logout
    });
});
于 2013-05-03T17:08:43.207 回答
1

我会以不同的方式考虑这一点以简化它。首先,编写一个处理一个用户的函数,返回一个为该用户完成处理的承诺:

function one_user(v){
    return $.post(loginURL, {user: v.username, passwrd: v.password})
    .then(function(data) {
        if (data <= 0) { throw "Login failed."; }
        console.log('Logged In!');
        return $.post(pollURL + 'select.php', {id: 143});
    })
    .then(function(data) {
        if (data === 'selected') {throw 'Already have a selection.';}
        return $.post(pollURL + 'submit.php');
    })
    .then(function(data) {
        if(data > 1) {
            Console.log('Successfully Voted.');
        } else {
           // if possible return to the login?
        }
    })
    .fail(function(e) {console.log("Error: "+e);})
   ;
}

请注意,我已将错误处理替换为与最后throw一起使用的fail,这是一种处理“错误”的更像 Promise 的方式。

现在,您的顶级序列无非是

$.when(   function() {return one_user(user1);})
    .then(function() {return one_user(user2);})
    .then(function() {console.log("All done!");};

请注意,上面传递给 when/then 的函数本身就是返回 Promise。这是编写基于 Promise 的代码的常见模式,它允许您将问题分解为单独的 Promise 序列,然后将它们串在一起。

如果你有多个用户user_array,虽然不同的 Promise 框架处理这个问题的方式略有不同,但使用 的方法很简单reduce,所以:

user_array.reduce(
    function(prev,cur){
        prev=prev.then(function(){return one_user(cur);});
    }),
    $.Deferred().resolve()
)
.then(function() {console.log("All done!");})
;
于 2013-05-19T10:45:28.590 回答