Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/36.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Node.js中的同步请求_Javascript_Node.js - Fatal编程技术网

Javascript Node.js中的同步请求

Javascript Node.js中的同步请求,javascript,node.js,Javascript,Node.js,如何使Node.js中的“request”模块以同步方式加载内容?我所看到的最好的建议是以某种方式使用回调函数,使函数在完成之前不返回自身。我试图在代码中内联使用“request”函数(需要根据不能放在回调中的数据进行处理) 那么,我如何使用'request'模块的回调来阻止它在加载完资源之前返回自身呢 我所做的是运行一个循环,从API下载两个值,然后根据这些值进行一些计算。虽然计算可以在回调中完成。。。循环将在没有执行下一个操作所需的值的情况下前进。(因此,在数据准备就绪之前停止循环将解决问题

如何使Node.js中的“request”模块以同步方式加载内容?我所看到的最好的建议是以某种方式使用回调函数,使函数在完成之前不返回自身。我试图在代码中内联使用“request”函数(需要根据不能放在回调中的数据进行处理)

那么,我如何使用'request'模块的回调来阻止它在加载完资源之前返回自身呢

我所做的是运行一个循环,从API下载两个值,然后根据这些值进行一些计算。虽然计算可以在回调中完成。。。循环将在没有执行下一个操作所需的值的情况下前进。(因此,在数据准备就绪之前停止循环将解决问题)


简单的回答是:不要。如果您想要线性读取的代码,请使用像seq这样的库。但不要期望同步。你真的不能。这是件好事

几乎没有什么东西不能放入回调中。如果它们依赖于公共变量,则创建一个闭包来包含它们。手头的实际任务是什么

您希望有一个计数器,并且只在数据存在时调用回调:

var waiting = 2;
request( {url: base + u_ext}, function( err, res, body ) {
    var split1 = body.split("\n");
    var split2 = split1[1].split(", ");
    ucomp = split2[1];
    if(--waiting == 0) callback();
});

request( {url: base + v_ext}, function( err, res, body ) {
    var split1 = body.split("\n");
    var split2 = split1[1].split(", ");
    vcomp = split2[1];
    if(--waiting == 0) callback();
});

function callback() {
    // do math here.
}

2018年更新:node.js在最新版本中支持async/await关键字,并且通过将异步流程表示为承诺的库,您可以等待它们。您可以通过程序获得线性、连续的流程,其他工作可以在您等待的过程中进行。它构建得非常好,值得一试。

您应该看看名为


并尝试使用async.series调用解决您的问题。

Aredridels的答案相对较好(对它进行了投票),但我认为它缺少等效的循环。这将有助于您:

同步代码等效项:

while (condition) {
  var data = request(url);
  <math here>
}
return result;
while(条件){
var数据=请求(url);
}
返回结果;
用于串行执行的异步代码:

function continueLoop() {
  if (!condition) return cb(result);
  request(url, function(err, res, body) {
    <math here>
    continueLoop()
  })
}
continueLoop()
函数continueLoop(){
如果(!条件)返回cb(结果);
请求(url、函数(err、res、body){
continueLoop()
})
}
continueLoop()

虽然node.js的本质可能是异步样式,通常不应该这样做,但有时您希望这样做

我正在编写一个方便的脚本来检查一个API,并且不想因为回调而把它搞砸

Javascript不能执行同步请求,但C库可以


简单的回答是:不要。(…)你真的不能。这是件好事

我想澄清这一点:

NodeJS不支持。它的设计并不是为了支持他们开箱即用,但是如果你足够热衷,这里有一些变通方法,下面是一个例子:

var request = require('sync-request'),
    res1, res2, ucomp, vcomp;

try {
    res1 = request('GET', base + u_ext);
    res2 = request('GET', base + v_ext);
    ucomp = res1.split('\n')[1].split(', ')[1];
    vcomp = res2.split('\n')[1].split(', ')[1];
    doSomething(ucomp, vcomp);

} catch (e) {}
当您打开“同步请求”库上的引擎盖时,您可以看到它在后台运行同步。正如sync请求中所解释的,应该非常谨慎地使用它。这种方法锁定主线程,这对性能不利

但是,在某些情况下,编写异步解决方案几乎没有或根本没有好处(与编写更难阅读的代码所造成的某些伤害相比)

这是其他语言(Python、Java、C#等)中许多HTTP请求库的默认假设,这一理念也可以应用到JavaScript中。语言毕竟是解决问题的工具,如果利大于弊,有时您可能不想使用回调

对于JavaScript纯粹主义者来说,这可能是异端邪说,但我是一个实用主义者,因此我可以清楚地看到,如果您发现自己处于以下某些场景中,使用同步请求的简单性会有所帮助:

  • 测试自动化(测试本质上通常是同步的)

  • 快速API mashup(即hackathon、概念验证等)

  • 帮助初学者的简单示例(前后)


  • 请注意,上述代码不应用于生产。如果你要运行一个合适的API,那么就使用回调、承诺、异步/等待等等,但除非你想为服务器上浪费的CPU时间付出巨大代价,否则就不要使用同步代码。

    2018年,你可以在Node.js中使用
    async
    wait
    来编程“常规”风格

    下面是一个示例,它将请求回调包装在承诺中,然后使用
    await
    获取解析值

    const request = require('request');
    
    // wrap a request in an promise
    function downloadPage(url) {
        return new Promise((resolve, reject) => {
            request(url, (error, response, body) => {
                if (error) reject(error);
                if (response.statusCode != 200) {
                    reject('Invalid status code <' + response.statusCode + '>');
                }
                resolve(body);
            });
        });
    }
    
    // now to program the "usual" way
    // all you need to do is use async functions and await
    // for functions returning promises
    async function myBackEndLogic() {
        try {
            const html = await downloadPage('https://microsoft.com')
            console.log('SHOULD WORK:');
            console.log(html);
    
            // try downloading an invalid url
            await downloadPage('http://      .com')
        } catch (error) {
            console.error('ERROR:');
            console.error(error);
        }
    }
    
    // run your async function
    myBackEndLogic();
    
    const request=require('request');
    //用承诺包装一个请求
    函数下载页(url){
    返回新承诺((解决、拒绝)=>{
    请求(url,(错误、响应、正文)=>{
    如果(错误)拒绝(错误);
    如果(response.statusCode!=200){
    拒绝(“无效状态代码”);
    }
    决议(机构);
    });
    });
    }
    //现在以“常规”方式编程
    //您只需使用异步函数并等待
    //对于返回承诺的函数
    异步函数myBackEndLogic(){
    试一试{
    const html=wait downloadPage('https://microsoft.com')
    log('SHOULD WORK:');
    log(html);
    //尝试下载无效的url
    等待下载页面('http://.com')
    }捕获(错误){
    console.error('error:');
    控制台错误(error);
    }
    }
    //运行异步函数
    myBackEndLogic();
    
    您可以对请求库执行完全类似的操作,但这是使用
    consthttps=require('https')进行同步的
    consthttp=require('http'),应随节点一起提供

    举个例子,

    consthttps=require('https');
    常量http_get1={
    主持人:“www.googleapis.com”,
    端口:'443',
    路径:'/youtube/v3/search?arg=1',
    方法:“GET”,
    标题:{
    “内容类型”:“应用程序/json”
    }
    };
    常数http\u ge
    
    const request = require('request');
    
    // wrap a request in an promise
    function downloadPage(url) {
        return new Promise((resolve, reject) => {
            request(url, (error, response, body) => {
                if (error) reject(error);
                if (response.statusCode != 200) {
                    reject('Invalid status code <' + response.statusCode + '>');
                }
                resolve(body);
            });
        });
    }
    
    // now to program the "usual" way
    // all you need to do is use async functions and await
    // for functions returning promises
    async function myBackEndLogic() {
        try {
            const html = await downloadPage('https://microsoft.com')
            console.log('SHOULD WORK:');
            console.log(html);
    
            // try downloading an invalid url
            await downloadPage('http://      .com')
        } catch (error) {
            console.error('ERROR:');
            console.error(error);
        }
    }
    
    // run your async function
    myBackEndLogic();
    
    var request = require('sync-request');
    var res = request('GET', 'http://example.com');
    console.log(res.getBody());