【问题标题】:Difficulties with Bluebird Promise.bind()Bluebird Promise.bind() 的困难
【发布时间】:2016-04-29 06:42:54
【问题描述】:

我正在尝试按顺序调用一系列承诺。我想在所有承诺中传递一些状态。我以为我可以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);

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

【问题讨论】:

  • 我不认为你可以bind Promises;您可能需要绑定其中的功能。
  • 您是否注意到您没有在任何地方使用函数参数??
  • @Hamms:这是蓝鸟,不是原生承诺。
  • 抱歉,是的,我发帖时忘记清理函数参数,函数参数是bind() 等各种尝试的一部分。

标签: javascript promise bluebird


【解决方案1】:

好的,让我们看看能做些什么。

我们可以从将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));

【讨论】:

  • 非常感谢您的详细记录。您的解决方案效果很好。我确实尝试绑定到“任务”,但没有意识到 this 在 Promise 回调中被更改。
猜你喜欢
  • 1970-01-01
  • 2019-07-16
  • 2017-04-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多