简体   繁体   English

承诺然后绑定问题

[英]Promise.then bind issue

I have been facing an issue in binding a value to next Promise. 我在将值绑定到下一个Promise时遇到一个问题。 Look at the following code, it will explain the situation better. 看下面的代码,它将更好地说明情况。

'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'
});

The question is, why the value it binds is different for both cases. 问题是,为什么两种情况下绑定的值都不同。 Both are exactly the same, except this one is first resolving the part of promise and then assigning a value to payload.userId . 两者是完全一样的,只不过这是先解决promise的一部分,然后将值分配给payload.userId

Let's break down your code a little bit. 让我们分解一下代码。 You have 你有

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));
}

the issue is that your .bind will run before your callback. 问题是您的.bind将在回调之前运行。 This code could also be written as 该代码也可以写成

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);
}

The payload object is shared across everything, but the payload.userId is passed into .bind before firstThenCallback has had a chance to execute. payload对象跨所有共享,但payload.userId传递到.bind之前firstThenCallback有机会来执行。

Rather that using .bind and passing the value immediately, it seems like your simplest solution would be to use an anonymous function so the userId value is only read later. 而是使用.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));
}

It's not at all clear why you've written such round-about promise code either, but I assume this is a trimmed-down example? 完全不清楚为什么您也编写了这种环绕式答应代码,但是我认为这是一个精简的示例? Why are you resolving with payload instead of just calling FindUser in that function, eg 为什么要使用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