链式蓝鸟的奇怪执行顺序.then()s

时间:2014-10-03 14:12:58

标签: javascript promise bluebird

有人可以向我解释为什么以下两个链式功能:

// returns zero if okay
var resetCounter = function (model) {

return new Promise(function (resolve, reject) {

model.resetCount(function (error, result) {
  if (error) {
    console.log(error);
    reject(error);
      } else {
        console.log(result);
        resolve(result);
      }
    });
  });
};


// returns the amount of deleted entries
var clearCollection = function (collection) {
  collection.remove({}, function (error, result) {
    if (error) {
      console.log(error);
      return Promise.reject(error);
    } else {
      console.log(result);
      return Promise.resolve(result);
    }
  });
};

// chaining for demo purposes
var reset = function () {
  return resetCounter(nm)
    .then(console.log('1 -> After newsmodel'))
    .then(resetCounter(sm))
    .then(console.log('2 -> After schoolmodel'))
    .then(resetCounter(um))
    .then(console.log('3 -> After usermodel'))
    .then(clearCollection(nm))
    .then(console.log('4 -> After clearing all news'))
    .then(clearCollection(sm))
    .then(console.log('5 -> After clearing all schools'))
    .then(clearCollection(um))
    .then(console.log('6 -> After clearing all users'))
    .catch(function (error) {
      console.log(error);
    });
};

产生以下输出:

1 -> After newsmodel
2 -> After schoolmodel
3 -> After usermodel
4 -> After clearing all news
5 -> After clearing all schools
6 -> After clearing all users
7 -> After inserting news
8 -> After inserting schools
9 -> After inserting users
0
0
0
30
500
100

在这种情况下我有一个插入功能,我省略了。在所有内容都被清除后,它再次填充数据库......

我的预期结果是:

0
1 -> After newsmodel
0
2 -> After schoolmodel
0
3 -> After usermodel
500
4 -> After clearing all news
100
5 -> After clearing all schools
30
6 -> After clearing all users
7 -> After inserting news
8 -> After inserting schools
9 -> After inserting users

要清除它!在这种情况下,我对承诺的结果不感兴趣。我只对异步操作的执行顺序感兴趣。这就是为什么我没有将任何成功或错误传递给.then()。我试图取代" bluebird" "当"没有成功,这清楚地告诉我,我总是错过了一些关于承诺的重要事情。我带来的大多数例子都是使用以下.then()中的promise的结果,再次,在这种情况下,我并不感兴趣。

我做错了什么?

1 个答案:

答案 0 :(得分:1)

  

我只对异步操作的执行顺序感兴趣。这就是为什么我没有将任何成功或错误传递给.then()。我带来的大多数例子都是使用以下.then()中的promise的结果,再次,在这种情况下我不感兴趣。

你没有使用来使用结果参数,但你总是需要传递一个回调函数,承诺可以在以后执行

  

我遗漏了一些关于承诺的重要事项

promise表示操作的结果,而不是操作本身。这意味着当你有一个承诺时,任务已经开始了。您需要使用可以执行的函数,然后返回一个承诺。

  

我做错了什么?

.then()方法确实期望这样一个函数 - 当promise的结果(无论它是什么)到达时调用。该函数不需要使用该结果,但必须可调用

在你的情况下,你传递的内容如下:

  • console.log(…) - 立即记录参数并传递undefined
  • resetCounter(um)) - 立即调用异步函数并将promise传递给then,忽略它(因为它不是函数)
  • clearCollection(nm) - 会立即调用异步函数,但clearCollection不会返回任何内容,因此我们会返回undefined

例如,

// returns the amount of deleted entries
var clearCollection = function (collection) {
  collection.remove({}, …);
};

实际上并不return。您使用return的唯一部分是内部回调,它没有意义。您需要构建一个类似于Promise函数的resetCounter - 或者您只需使用Promisification feature

function clearCollection(collection) {
     return Promise.promisify(collection.remove, collection)({});
}

现在,你的链应该是这样的:

resetCounter(nm)
.then(function() {
    console.log('1 -> After newsmodel');
    return resetCounter(sm);
})
.then(function() {
    console.log('2 -> After schoolmodel');
    return resetCounter(um);
})
.then(function() {
    console.log('3 -> After usermodel');
    return clearCollection(nm);
})
.then(function() {
    console.log('4 -> After clearing all news');
    return clearCollection(sm);
})
.then(function() {
    console.log('5 -> After clearing all schools');
    return clearCollection(um);
})
.then(function() {
    console.log('6 -> After clearing all users');
}, function (error) {
    console.log(error);
});