我一直面临着将值绑定到下一个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
赋值。
答案 0 :(得分:3)
让我们分解你的代码。
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);
});
}