首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在循环中创建promises

在循环中创建promises
EN

Stack Overflow用户
提问于 2017-01-16 20:43:07
回答 2查看 180关注 0票数 0

我必须根据给定的配置文件在循环中创建promises,并在所有问题都得到解决后返回响应。代码是这样的-

代码语言:javascript
复制
{for(let type in spotlight){
    switch (type){
        case "outliers":{
                let ops= spotlight[type];
                for(let i=0;i<ops.length;i++){
                    (function(op){
                        let p= new Promise(function(resolve,reject){
                            let reqUrl= urlCreator(op.uri,op.query);
                            //console.log("--------------------"+reqUrl);

                            apiService.get(reqUrl,function(isSuccess,data){
                                if(!isSuccess){
                                    return reject(data);
                                }
                                // console.log(isSuccess);
                                // console.log(data);
                                // console.log("trend is ------"+JSON.stringify(op));
                                // create objects array
                                // let temp= [];
                                // let overallScore= data.overall.score;
                                // for(let day in overallScore){
                                //     temp.push({"key": day,"value": parseFloat(overallScore[day])});
                                // }
                                //let outliers= stats.outliers(temp,"key","value");
                                resolve({"type":type,"name": op.name,"data": outliers});

                            })
                        });
                        promiseArray.push(p);   
                    }(ops[i]))           
                }
                break;    
            }

        case "filters":{
                let ops= spotlight[type];
                for(let i=0;i<ops.length;i++){
                    (function(op){
                        let p= new Promise(function(resolve,reject){
                            let reqUrl= urlCreator(op.uri,op.query);
                            apiService.get(reqUrl,function(isSuccess,data){
                                if(!isSuccess){
                                    return reject(data);
                                }
                                // console.log(isSuccess);
                                // console.log(data);
                                // console.log("coc is ------"+JSON.stringify(op));
                                resolve({"type": type,"name": op.name,"data": data});

                            })
                        })
                        promiseArray.push(p);
                    }(ops[i]))
                }
             break;     
            }   
    }
}

Promise.all(promiseArray).then(values=>{
    return res.json(values); 
},
reason=>{

    return res.json(reason);
}).catch(reason=>{
    return res.json(reason);
})}

问题是,承诺永远不会回来,既不会解决,也不会被拒绝。

根据配置文件,它必须命中两个URL,比如u1和u2。我尝试记录输出,以查看哪些请求正在返回。当服务器启动并发出第一个请求时,U1将返回并挂起请求。在刷新时,我收到来自U2的响应,U2和请求挂起,然后在刷新时再次U1,U1,这将继续。在我看来,由于某种原因,只返回一个请求,而另一个请求则位于缓冲区或其他地方,并在发出下一个请求时出现。这两个请求都只发送到本地服务器,我将其路由到外部只是为了利用缓存,因为url被用作缓存的关键字。

我试过使用facebook.com和google.com这样的虚拟url,它工作得很好,一个本地url,另一个像facebook.com也可以,但是当两个url都是本地服务器的时候,它就卡住了。

这是否与节点的单线程性质有关,或者是因为使用相同的套接字来发出两个请求。

PS- I使用npm-request进行URL调用。

EN

回答 2

Stack Overflow用户

发布于 2017-01-17 04:06:09

也许在提出第二个请求之前犹豫不决会解决你的问题。

我做了一些工具,可以帮助你做到这一点。请参阅MacroQTools.js文件,网址为

https://github.com/J-Adrian-Zimmer/JavascriptPromisesClarified.git

票数 0
EN

Stack Overflow用户

发布于 2017-01-17 06:29:29

您将request回调定义为function(success , data),而request使用像function(error , response)一样定义的错误优先回调。

您调用的请求如下:

代码语言:javascript
复制
apiService.get(reqUrl,function(isSuccess,data){
    if(!isSuccess){
        return reject(data);
    }
    // console.log(isSuccess);
    // console.log(data);
    // console.log("coc is ------"+JSON.stringify(op));
    resolve({"type": type,"name": op.name,"data": data});

});

假装,如果第一个参数丢失,您必须用第二个参数data拒绝它。然而,实际上,它应该是这样的:

代码语言:javascript
复制
    apiService.get(reqUrl,function(err,data){
    if(err){
        reject(err);
    }
    else{
        // console.log(isSuccess);
        // console.log(data);
        // console.log("coc is ------"+JSON.stringify(op));
        resolve({"type": type,"name": op.name,"data": data});
    }

});

因为request期望错误优先回调(就像节点中接受回调的几乎任何东西一样)。

因此,当请求实际按预期工作时,您的代码必须实际拒绝具有实际实值的承诺,因为当request工作时,isSuccess为空,而data具有实际响应值。

这肯定破坏了一些东西,这是不好的,虽然仅仅修复它可能不能完全解决你的问题:我认为你的请求行为奇怪是因为你的api的一些配置问题,而不仅仅是因为当请求成功时你拒绝了承诺(这将只是send数据作为拒绝的原因)。

另外,您将两次处理Promise.all()的拒绝,将第二个处理程序传递给then并再次调用catch。只需要一个,那就是.catch(handler) is probably better

我做了一个关于如何使用Promise.all收集异步请求的小工作示例。我使用imdb作为apiService,但任何异步http服务也可以。我没有完全复制你的代码,但我相信你可以调整它来使你的代码工作,至少是使用http服务的那部分代码。

代码语言:javascript
复制
var express = require('express');
var app = express();
var Promise = require('bluebird');
var imdb = require('imdb-api');

app.get('/', controllerHandler );

app.listen(3000, function () {
  console.log('Example app listening on port 3000!')
});


var apiService = {}
apiService.get = imdb.getReq;


function controllerHandler(request , response){
    //like iterating through spotlight.type and returning an array of promises from it.
    //in this case the array is from films and Airbag is obviously the best of them
    var promises = [{name : 'The Matrix'} , { name : 'Avatar'} , {name : 'Airbag'}].map( createPromise );

    //use either .catch(errorHandler) or then( successHandler , errorHandler ). The former is the better:
    Promise.all(promises).then( successHandler ).catch( errorHandler );

    function successHandler(result){
        return response.json(result);
    }

    function errorHandler(reason){
        console.log('There was an error calling to the service:');
        console.log(reason);
        return response.send('there was an error');
    }
}

function createPromise(film){
    return new Promise( function(resolve , reject){
        apiService.get(film , function(err , data){
            if(err)
                reject( new Error(err));
            else
                resolve( {title : data.title , year : data.year} );
        });
    });
};
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41676698

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档