蓝鸟 Promise.bind() 的困难

Difficulties with Bluebird Promise.bind()

我正在尝试按顺序调用承诺链。我想在所有承诺中传递一些状态。我以为我可以 bind() 我的状态,但一直无法让它工作。我的示例代码如下所示:

var Promise = require('bluebird');
...
function op1(state) {
    return new Promise(function(resolve, reject) {
        this.num += 1;
        resolve();
    });
}
function op2(state) {
    return new Promise(function(resolve, reject) {
        this.num += 1;
        resolve();
    });
}
function op3(state) {
    return new Promise(function(resolve, reject) {
        this.num += 1;
        resolve();
    });
}

function sequence(tasks, state) {
    var current = Promise.cast();
    for (var k = 0; k < tasks.length; ++k) {
        current = current.thenReturn().then(tasks[k]);
    }
    return current.thenReturn();
}

var state = { yadda: "yadda",
                      num:   0 };
var q = [ op1, op2, op3 ];

var p   = sequence( q, state );
var ret = p()
            .then( function(val) {
                console.log(val);
            })
            .catch ( function(val) {
                console.error(val);
            });

我已尝试将问题简化为我在许多示例中看​​到的内容:

op1().bind(state).then(op2).then(op3); 

但是,这也不起作用。

我还尝试将 sequence() 更改为以下内容(除其他外):

var current = Promise.cast().bind(state);

我对承诺还是很陌生。我怀疑我错过了一些简单的东西。任何建议或帮助将不胜感激。

好的,让我们看看可以做什么。

我们可以从绑定 state 到每个任务开始。

function sequence(tasks, state) {
    var current = Promise.resolve();
    for (var k = 0; k < tasks.length; ++k) {
        const taskWithState = tasks[k].bind(state);
        current = current.then(taskWithState);
    }
    return current;
}

我已经使用 bindthis 内部任务设置为 state,所以:

function op1() {
    // this === state
    return new Promise(function(resolve) {
        // this === window
        this.num += 1;
        resolve();
    });
}

如您所料,我们传递给 Promise 的函数会创建自己的上下文,因此 this 不会像我们希望的那样指向 state

为了绕过这个问题,我们可以使用一个老技巧,将上下文保存在一个变量中(比如 var that = this),或者我们可以只使用箭头函数,它不会创建自己的上下文。考虑到这一点:

function op1() {
    // this === state
    return new Promise(resolve => {
        // this === state
        this.num += 1;
        resolve();
    });
}

大家在一起

function op1() {
    return new Promise(resolve => {
        this.num += 1;
        resolve();
    });
}

function op2() {
    return new Promise(resolve => {
        this.num += 1;
        resolve();
    });
}

function op3() {
    return new Promise(resolve => {
        this.num += 1;
        resolve();
    });
}

function sequence(tasks, state) {
    let current = Promise.resolve();
    for (let k = 0; k < tasks.length; ++k) {
        const taskWithState = tasks[k].bind(state);
        current = current.then(taskWithState);
    }
    return current;
}

var state = { yadda: "yadda", num:  0 };
var q = [ op1, op2, op3 ];

sequence(q, state)
  .then(() => console.log(state))
  .catch(err => console.error(err));