实现时,将承诺数组转换为值数组
Transform array of promises into array of values when fulfilled
我正在寻找一个函数,该函数将返回promise的解析值。优雅地失败无疑是一种奖励,但这是一个假定的前提条件,即当调用函数时,promise就可以得到解决。
当我使用webdriver.js promise实现时,它允许类似于下面的队列操作,我不想在队列/链等的语义中迷失太多。仅出于这个原因,这里有一些伪代码来覆盖我试图实现的内容:
var inputs = [...], outputs;
outputs = inputs.map(function(input){
//queue some async tasks to be performed with input
queue.enqueue(...);
//I can't return the *output* value here yet, naturally, so instead
return promise;
});
//now I'll add another task to the same queue
//this means that by the time this task is run
//the async tasks above would have been executed
//and the promises would be "resolvable"... right?
queue.enqueue(function(){
console.log(outputs); //>an array of promises
console.log(doSomeMagic(outputs)); //>resolved values as needed <<<
});
注意:afaik Q.all()
不会做我要做的事情-它接受一个promise数组,并返回一个数组的promise,而不是其解析值。我很高兴被证明是错的。
对于其他想要根据问题标题寻找答案的人,以下与ES 2017+一起使用,以获取一系列承诺并返回一系列值:
var arrayOfValues = await Promise.all(arrayOfPromises)
获取promise最终值的唯一方法是使用then
。如果函数异步执行工作,它必须返回promise,并且在任何情况下都不能返回纯值。要做到这一点,它必须阻塞执行线程,直到工作完成,这只有线程或光纤才能实现,这会带来死锁和交织的危险。
因此,Q.all
实际上是您需要的方法,除了使用then
来获得最终值。
Q.all(inputs.map(function (input) {
return promiseForOutput; // however you go about this
}))
.then(function (outputs) {
// at this event, outputs is an array of output values
});
当然,有作弊的方法。promise.inspect()
将返回一个描述promise状态的对象,如{state: "fulfilled", value: value}
(如果它已准备好)、{state: "rejected", error}
(如果它失败)或{state: "pending"}
(如果它尚未准备好)。如果,正如你所说,你保证Q.all
返回的outputs
承诺已经实现,你可以这样做:
outputs = outputs.inspect().value
我不建议这样做。知道承诺已被解决的最好方法是使用then
。
如果您还可以通过一些外部手段保证所有outputs
都准备好了,那么您也可以将值推送到您制作的outputs
数组中。
var endResult = Q.defer();
var outputs = [];
inputs.forEach(function (input) {
outputPromise.then(function (output) {
outputs.push(output);
check();
}, endResult.reject);
});
check();
function check() {
if (outputs.length === inputs.length) {
// manipulate outputs directly, they are ready
endResult.resolve();
}
}
return endResult.promise;
然而,最好的方法是只使用Q.all(outputs).then
来获得一个事件,该事件保证在所有输出就绪之后发生。
由于您通常不知道promise是否已解析,因此无法简单地将其转换为普通值。Q.all
必须返回promise,因为它无法从异步上下文中提取值数组。你唯一知道承诺有价值的时候是在成功处理程序中,无论如何你都会得到价值。你不应该使用另一个事件系统告诉你什么时候一个承诺已经解决-使用承诺本身。
所以而不是使用queue.enqueue
,只需放入Q.all(outputs).then(function(values){ /* do something */ })
。但是,如果您不能解决这个问题,您可以查看Promise inspect
调试方法:_.pluck(_.invoke(outputs, "inspect"), "value")
。但请注意,那时可能更容易不将价值观存储在承诺中。
- 使用JS将数组转换为json对象
- 本地存储中的字符串到字节数组转换
- Javascript函数,用于将数组转换为“;2-元组”;
- php数组转换为javascript
- 在Javascript中将一个值和字符串数组转换为if语句
- 将数组转换为javascript格式的字符串
- 如何将数组转换为有效的json
- JSON数组转换为JS对象数组
- 如何将数组转换为映射
- JavaScript:将字符串数组转换为文本区域
- javascript |数组转换
- 数组转换为多个字符串
- Javascript将数组转换为字符串并使其反向输出
- 将Byte数组转换为Angularjs中的Base64字符串
- 将对象数组转换为与nodejs/pg/unnest兼容的数组
- 将Javascript数组转换为PHP数组
- 将数组转换为键值对
- 使用Ramda将对象数组转换为普通对象
- javascript将对象数组转换为字符串以存储在s3中
- 使用.join方法将数组转换为不带逗号的字符串