正确地束缚承诺

时间:2016-01-04 13:55:01

标签: javascript node.js promise

我想在循环内顺序绑定promises。我需要这个用户帐户,其中一个操作的结果取决于另一个操作。 我正在尝试编写一个平面版本 - 所有代码都在一个地方,使用bind。这至少是我想要的。我将承诺包含在两个创建方法中,如下所示:

function create(myApi, record) {
    return new Promise(function (resolve, reject) {
            myApi.create(record, function (err, result) {
                    if (err) reject(err);
                    else resolve(result);
            });
    });
}

function createUser(myApi, record) {
    return new Promise(function (resolve, reject) {
            myApi.createUser(record, function (err, result) {
                    if (err) reject(err);
                    else resolve(result);
            });
    });
}

现在,我想在循环中创建用户:

for ( var i = 0; i < dummyData.accounts.length; i++) {
  var cursorUser = dummyData.accounts[i];
  var auth0User = {
    email: cursorUser.email,
    password: cursorUser.password,
    connection: 'Username-Password-Authentication'
  };
  createUser(api, auth0User)
    .then( function(auth0Info) {
      console.log("Auth0 userInfo: ", auth0Info);
      cursorUser.authProfile = auth0Info;
      create(accountsAPIService, cursorUser)
        .then(function (account) {
          console.log("created account:", account);
        })
        .catch(function (err) {
          console.log('count not create account for user, error: ', err, '\nfor: ', auth0User);
        });
  })
  .catch(function (err) {
    console.log('could not create auth0 user, error: ', err, '\nfor: ', auth0User);
  });
}

由于这两个方法是异步的,因此它当然无法正常工作。呼叫不按顺序执行。我想链接promises,以便在createUser的调用返回之前create不会运行。尝试使用绑定,但它不适合我。应该如何进行顺序链接?我绑定了createUser的.then?请指教。

2 个答案:

答案 0 :(得分:3)

当您从then返回承诺时,then之后的链接将使用该承诺而非原始承诺解析/拒绝。

createUser(api, auth0User).then(function(auth0Info) {
  cursorUser.authProfile = auth0Info;

  // Return create's promise
  return create(accountsAPIService, cursorUser);

}, function (err) {
  console.log('could not create auth0 user, error: ', err, '\nfor: ', auth0User);
})
// This will wait for create's promise instead of createUser's promise
.then(function (account) {
  console.log("created account:", account);
}, function (err) {
  console.log('count not create account for user, error: ', err, '\nfor: ', auth0User);
})

答案 1 :(得分:0)

使用ES6,您可以使用生成器,它们允许您在异步时执行异步写入任务。在这个例子中,我使用的是bluebird,但是还有其他很有效的选项。

var CreateUserGenerator = BPromise.coroutine(function * (arg) {
    for ( var i = 0; i < dummyData.accounts.length; i++) {
      var cursorUser = dummyData.accounts[i];
      var auth0User = {
        email: cursorUser.email,
        password: cursorUser.password,
        connection: 'Username-Password-Authentication'
    };
    var auth0Info =  yield createUser(api, auth0User);
    console.log("Auth0 userInfo: ", auth0Info);
    cursorUser.authProfile = auth0Info;
    var account = yield create(accountsAPIService, cursorUser)
    console.log("created account:", account);         
    }
}

function generateorWithCatch (argument) {
    creatLoopUser(arg)
    .catch(function (err) {
        console.log('could not create auth0 user, error: ', err, '\nfor: ', auth0User);
    });
}

在此解决方案中,我假设您的create和createUser函数已写入并正确返回值