[英]Promise.all() doesn't work after a previous promise in a co() function
下面的代码正常工作:
"use strict"
const request = require('request-promise-native')
const co = require('co')
function getResults() {
return co(function *() {
//yield request('http://www.google.es').then(res => {
// console.log('Request 1')
//})
const paginatedResources = [
'http://www.yahoo.com',
'http://www.gmail.com'
]
const promises = []
paginatedResources.forEach((uri) => {
promises.push(request(uri))
})
Promise.all(promises).then(function(res) {
console.log('Request 2 and 3') //Order doesn't matters
})
})
}
getResults()
Promise.all()返回期望值,但是如果我取消注释第8行( yield ... ),则Promise.all似乎无法解析(控制台日志2和3消息未出现)。 为什么第一个承诺的解决会影响第二个承诺?
您的函数未返回任何内容:
return co(function *() {
//let firstPageResponse = yield request(getListConfiguredResource(filterBy)).then((res) => { return res })
//let paginatedResources = getAllPaginatedResources(firstPageResponse.headers)
let paginatedResources = [
'https://api.github.com/users/jvcalderon/gists?per_page=100&page=1',
'https://api.github.com/users/jvcalderon/gists?per_page=100&page=2',
'https://api.github.com/users/jvcalderon/gists?per_page=100&page=3'
];
//here you should return something
return Promise.all(
paginatedResources.map(
url => request(getBaseConfiguredResource(url))
)
);
})
如果您想要一个预取所有资源的迭代器,则无法返回解析值,因为您不知道使用者何时要调用next()
以及消费者何时进行了任何异步处理。 因此,消费者必须履行承诺:
/*
causes a promise returning function not to be called
untill less than max are active
usage example:
max2 = throttle(2);
functions = [fn1,fn2,fn3...fn100];//functions returning promise
params = [param1,param2,param3...param100]
Promise.all(//even though a 100 promises are created, only 2 are active
functions.map(
(fn,index)=>
max2(fn)(params[index])
.then(...)
)
)
*/
const throttle =
(max) =>{
var que = [];
var running = 0;
const wait = function*(resolve,fn,arg){
return resolve(fn(arg));
};
const nextInQue = ()=>{
const it = que[0];
que=que.slice(1);
if(it){
it.next();
}
return true;
};
const queItem = (fn,arg)=>
new Promise(
(resolve,reject)=>que.push(wait(resolve,fn,arg))
)
;
return (fn)=>(arg)=>{
const p = queItem(fn,arg)
.then(x=>nextInQue() && x)
;
running++;
if(running<=max){
nextInQue();
}
return p;
};
}
;
/*
result.toPromse(result)
if result is type Error a rejected promise is returned
reject reason is result.val
if result is of type Value a resolved promise is returned
resolve is result.val
else a resolved promise is returned
resolve value is result
result toResult
if promise is rejected the rejection is caught
the promise resolves to a result of type Error
with val of reject reason
if promise is resolved
the promise resolves to a result of type Value
with val of resolved value
*/
const result = (function(){
const Error = function(val){this.val=val;}
const Value = function(val){this.val=val;}
return {
toResult:promise =>
promise.then(
val => new Value(val)
,reject => new Error(reject)
)
//a promise resolving in a result (Error or Value)
,toPromise:result =>
result.then(
x =>
(x.constructor === Error)
?Promise.reject(x.val)
:(x.constructor === Value)
?Promise.resolve(x.val)
:Promise.resolve(x)
)
}
})();
const test = function *() {
var i = -1;
//maximal 2 unresolved promises
const max2 = throttle(2);
const paginatedResources = [
'/index.html',
//causes fetch to return a rejected promise
'http://ldsjdslfjalksfljasdflkjasdflkjsdljla/error',
'/index.html'
];
//pre fetch all resources
const promises =
paginatedResources
.map(
url =>
//toResult causes any promise to resolve in a result
result.toResult(//max2(fetch)(url) gets uncaught in promise
max2(//maximal 2 active request (can change throttle)
fetch
)(url)
)
)
;
while(++i<promises.length){
yield promises[i];
}
}
//consuming the itirator
const it = test();
const consumeNext = () =>{
var v;
return (v = it.next()).done
?Promise.resolve("we are done")
//toPromise causes result type to convert in promise
// that is resolved or rejected based on result
// being Value or Error
:result.toPromise(v.value).then(x=>x.text())
}
consumeNext()
.then(
x=>console.log("first resouce:",x.length)
,reject=>console.warn(reject)
)
;
consumeNext()
.then(
x=>console.log("second resouce:",x.length)
,reject=>console.warn(reject)
)
;
consumeNext()
.then(
x=>console.log("third resouce:",x.length)
,reject=>console.warn(reject)
)
;
问题不在代码中。 它正常工作。 我在用于通过Mocha和'chai-as-promised'测试代码的测试套件中发现错误。 我有这样一行:
expect(getResults()).should.eventually.equal("foo")
但是应返回此结果以等待响应:
return expect(getResults()).should.eventually.equal("foo")
添加return语句使测试有效。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.