rob*_*ler 7 javascript ecmascript-6 es6-promise
我希望履行一些其他承诺的承诺.关键是我真的希望在第一个承诺完成后立即获得(仍在等待的)第二个承诺.不幸的是,一旦两个承诺都得到满足,我似乎只能获得第二个承诺的分辨率值.
这是我想到的用例:
var picker = pickFile();
picker.then( // Wait for the user to pick a file.
function(downloadProgress) {
// The user picked a file. The file may not be available just yet (e.g.,
// if it has to be downloaded over the network) but we can already ask
// the user some more questions while the file is being obtained in the
// background.
...do some more user interaction...
return downloadProgress;
}
).then( // Wait for the download (if any) to complete.
function(file) {
// Do something with the file.
}
)
Run Code Online (Sandbox Code Playgroud)
该函数pickFile
显示文件选择器,用户可以从自己的硬盘驱动器或URL中选择文件.它返回一个picker
用户选择文件后立即履行的承诺.此时,我们可能仍需要通过网络下载所选文件.因此,我无法picker
将所选文件作为分辨率值来实现.相反,picker
应该用另一个承诺来实现downloadProgress
,而这最终将通过所选文件来实现.
对于completenes,这是pickFile
函数的模拟实现:
function pickFile() {
...display the file picker...
var resolveP1 = null;
var p1 = new Promise(
function(resolve, reject) {
resolveP1 = resolve;
}
);
// Mock code to pretend the user picked a file
window.setTimeout(function() {
var p2 = Promise.resolve('thefile');
resolveP1(p2); // <--- PROBLEM: I actually want to *fulfill* p1 with p2
}, 3000);
return p1;
}
Run Code Online (Sandbox Code Playgroud)
在标记线的问题是,我想履行承诺p1
新的承诺p2
,但我只知道如何解决它.履行和解决之间的区别在于,如果提供的值p2
再次成为承诺,则解析首先检查.如果是,则履行p1
将被推迟到p2
完成,然后p1
将以p2
分辨率值而不是p2
其自身来实现.
我可以通过构建一个包装器来解决这个问题p2
,即更换线路
resolveP1(p2); // <--- PROBLEM: I actually want to *fulfill* p1 with p2
Run Code Online (Sandbox Code Playgroud)
来自第二个代码示例
resolveP1({promise: p2});
Run Code Online (Sandbox Code Playgroud)
然后,在第一个代码示例中,我必须替换该行
return downloadProgress;
Run Code Online (Sandbox Code Playgroud)
通过
return downloadProgress.promise;
Run Code Online (Sandbox Code Playgroud)
但是,当我真正想要做的只是履行(而不是解决)承诺时,这似乎有点像黑客.
我很感激任何建议.
除了我在问题中已经描述的解决方法之外,似乎没有其他解决方案。为了将来的参考,如果你想履行(而不是解决)一个p
带有 value 的Promise val
,其中另一个 Promise 是哪里,那么仅仅调用with argument 的val
Promise 解析函数将无法按预期工作。它将导致“锁定” 的状态,这样一旦满足,就会满足 的分辨率值(参见规范)。p
val
p
val
p
val
val
相反,包装val
另一个对象并p
使用该对象进行解析:
var resolveP; // Promise resolution function for p
var p = new Promise(
function(resolve, reject) {
resolveP = resolve;
}
);
function fulfillPwithPromise(val) { // Fulfills p with a promise val
resolveP({promise: val});
}
p.then(function(res) {
// Do something as soon as p is fulfilled...
return res.promise;
}).then(function(res) {
// Do something as soon as the second promise is fulfilled...
});
Run Code Online (Sandbox Code Playgroud)
如果您已经知道这val
是一个承诺,则此解决方案有效。如果您无法对 的val
类型做出任何假设,那么您似乎不走运。您必须始终将 Promise 解析值包装在另一个对象中,或者您可以尝试检测是否具有“function”类型的val
字段并有条件地包装它。then
也就是说,在某些情况下,承诺解析的默认行为实际上可能会产生预期的效果。因此,仅当您确定要履行而不是用第二个承诺来解决第一个承诺时,才使用上述解决方法。
归档时间: |
|
查看次数: |
3235 次 |
最近记录: |