繁体   English   中英

承诺然后绑定问题

[英]Promise.then bind issue

我在将值绑定到下一个Promise时遇到一个问题。 看下面的代码,它将更好地说明情况。

'use strict';

function FindEvent(eventId) {
    console.log('Event:', eventId);
    return Promise.resolve({title: 'MyEvent'});
}

function FindUser(userId) {
    console.log('User:', userId);
    return Promise.resolve({username: 'MyUser'});
}

function MyServiceProblem(payload) {
    payload.userId = 'blah';
    return FindEvent(payload.eventId)
        .then((event) => {
            payload.userId = 'test';
            // setting a breakpoint here shows
            // that the value to payload.userId has been
            // assigned, i.e. 'test'

            return Promise.resolve(payload);
        })
        .then(FindUser.bind(this, payload.userId));
        // But new value doesn't reaches inside FindUser
}

MyServiceProblem({ // userId is 'blah', why not 'test'
    eventId: '456'
});

function MyServiceWorks(payload) {
    payload.userId = 'blah';
    return new Promise((resolve) => {
        payload.userId = 'test';

        return resolve(payload);
    })
        .then(FindUser.bind(this, payload.userId));
        // From here, the 'test' value reaches FindUser
}

MyServiceWorks({ // userId is 'test'
    eventId: '456'
});

问题是,为什么两种情况下绑定的值都不同。 两者是完全一样的,只不过这是先解决promise的一部分,然后将值分配给payload.userId

让我们分解一下代码。 你有

function MyServiceProblem(payload) {
    payload.userId = 'blah';
    return FindEvent(payload.eventId)
        .then((event) => {
            payload.userId = 'test';

            return Promise.resolve(payload);
        })
        .then(FindUser.bind(this, payload.userId));
}

问题是您的.bind将在回调之前运行。 该代码也可以写成

function MyServiceProblem(payload) {
    payload.userId = 'blah';

    var firstThenCallback = (event) => {
        payload.userId = 'test';
        return Promise.resolve(payload);
    };
    var secondThenCallback = FindUser.bind(this, payload.userId);

    return FindEvent(payload.eventId)
        .then(firstThenCallback)
        .then(secondThenCallback);
}

payload对象跨所有共享,但payload.userId传递到.bind之前firstThenCallback有机会来执行。

而是使用.bind并立即传递值,似乎最简单的解决方案是使用匿名函数,以便稍后才读取userId值。

function MyServiceProblem(payload) {
    payload.userId = 'blah';
    return FindEvent(payload.eventId)
        .then((event) => {
            payload.userId = 'test';

            return Promise.resolve(payload);
        })
        .then(() => FindUser(payload.userId));
}

完全不清楚为什么您也编写了这种环绕式答应代码,但是我认为这是一个精简的示例? 为什么要使用payload来解决问题,而不是仅在该函数中调用FindUser ,例如

function MyServiceProblem(payload) {
    payload.userId = 'blah';
    return FindEvent(payload.eventId)
        .then((event) => {
            payload.userId = 'test';

            return FindUser(payload.userId);
        });
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM