如何在承诺中打破循环?

时间:2017-03-06 16:35:52

标签: javascript express promise sequelize.js

var ing_data = savedata.ingredients.split(',');    
for(var i =0; i<ing_data.length; i++){

      var d = {
            content_name: ing_data[i],
            dogFoodId: dogId
      }
      db.dog_ingredients.create(d).then(function(data){

      }, function(e){
            console.log(e);

            res.status(403).send('Error');
            //break for loop this point

      });
    }

如何在承诺中打破循环?

我正在使用node express,sequelize module

1 个答案:

答案 0 :(得分:2)

在触发第一个then回调之前,循环将结束;这是promises的保证之一(假设create操作返回一个正确的promise,而不仅仅是一个thenable;或者至少它返回的thenable异步完成)。

你可以使用reduce技巧循环添加连续这些成分(一次一个);一路上的承诺拒绝会跳过剩下的成分:

savedata.ingredients.split(',').reduce(function(p, ing) {
    // Chain this ingredient on the end of the promise, return
    // the new promise `then` returns, which gets passed to the
    // next iteration
    return p.then(function() {
        var d = {
            content_name: ing,
            dogFoodId: dogId
        };
        // Return the promise from `create`
        return db.dog_ingredients.create(d);
    });
}, Promise.resolve()/* Seeds the loop above */)
.catch(function(e) {
    // We got a rejection, which bypasses any pending resolution
    // handlers we set up above; process the rejection.
    console.log(e);
    res.status(403).send('Error');
    return Promise.reject(e); // Only need to propgate the rejection like this
                              // this if something will use the return value of
                              // this overall structure
});

看起来很大,但主要是注释和对象初始化器;我们也可以这样写(假设我们不需要传播拒绝):

savedata.ingredients.split(',').reduce(function(p, ing) {
    return p.then(function() {
        return db.dog_ingredients.create({ content_name: ing, dogFoodId: dogId });
    });
}, Promise.resolve())
.catch(function(e) {
    res.status(403).send('Error');
});

(或者你甚至可以变小,但对我来说,调试会受到影响 - 让缩小到缩小器。)

我假设您不想并行添加成分,因为您已表明要停止“第一个”错误。但如果你这样做,代码会更简单:

Promise.all(savedata.ingredients.split(',').map(function(ing) {
    return db.dog_ingredients.create({ content_name: ing, dogFoodId: dogId });
}).catch(function(e) {
    res.status(403).send('Error');
    return Promise.reject(e);
});

(假设我们不需要传播拒绝。)

但是,这是平行的。

相关问题