【问题标题】:Forcing an async node.js result in azure强制异步 node.js 导致天蓝色
【发布时间】:2019-08-09 14:36:46
【问题描述】:

我通常使用其他编程语言,虽然需要实现一些 node.js 代码,但我是全新的:现在,我只希望我的 azure 函数应用程序的结果实际上依赖于我调用api。我将 HTTP 调用放入一个 Promise 中并等待结果:

module.exports = async function (context, req) {
    context.res = {
        body: {
            "data": [{
                "value": "start"
            }]
        }
    };
    await callapi(context);
};

function callapi(context){
    var options = {
        host: 'jsonplaceholder.typicode.com',
        port: 443,
        path: '/todos/1',
        method: 'GET'
    };
    var p1 = new Promise(
        function(resolve, reject) {
            callback = function(httpres) {
                var str = '';
                response.on('error', function (err) {
                    context.res = {body: {"data": [{"value": "error"}]}};
                });
                httpres.on('data', function (chunk) {
                   str += chunk;
                });
                httpres.on('end', function () {          
                    resolve(str);
                });
            }
            https.request(options, callback).end();
        }
    );
    p1.then(function(reqhtml) {
        context.res = {
            body: {
                "data": [{
                    "value": "it worked"
                }]
            }
        };
    })
}

我对此的期望是它会 - 取决于是否可以访问服务器 - 返回(一个上下文)值“它工作”或“错误”,但是它不等待承诺而只是返回“开始”。

如何等待 Azure 中的异步功能?我没有除此之外的代码;这个函数只能通过另一个 API 调用,我只能通过图形用户界面以受限的方式操作结果。有没有办法强制 node.js 在这个函数中等待?

【问题讨论】:

  • 这个函数怎么调用?
  • @Thomas 在函数应用中使用 API。实际调用发生在用于流操作的 GUI 内,此时我对事物没有太多控制权;特别是我等不及了。
  • “我对事情没有太多的控制权;尤其是我等不及了。” 让我将其与现实世界的情景进行比较:你走进一家商店,然后告诉员工您需要第 XY 部分。他告诉你,他们(不再)没有这部分,需要订购,这需要几天时间。您的回答:“我等不及了”。所以现在怎么办?他们仍然没有零件,他们仍然需要订购它,交货仍然需要几天,无论您是否可以等待。 你将不得不等待至少如果你想要你的数据,就是这样。

标签: javascript node.js azure asynchronous httprequest


【解决方案1】:

我已经清理了你的代码。

module.exports = async function (context, req) {
    const value = await callapi();
    context.res = {
        body: {
            data: [{
                value
            }]
        }
    };
};

// this function does not need any parameters, 
// it's sole job is to make a https request to a static endpoint 
// and return a value based on wether there was an error or not
function callapi(){
    var options = {
        host: 'jsonplaceholder.typicode.com',
        port: 443,
        path: '/todos/1',
        method: 'GET'
    };

    return new Promise(function(resolve, reject) {
        const req = https.request(options, res => {
            let str = "";

            res.on('data', function(chunk) {
                str += chunk;
            });

            res.on('end', function() {
                resolve(str);
            });
        });

        res.on('error', reject);

        req.end();
    })
    .then(() => "it worked")
    .catch(() => "error");
}

现在,我只希望我的 azure 函数应用程序的结果实际上依赖于我调用 api。

由于您的callapi 没有返回任何内容,await callapi() 将返回await undefined,这将在下一个滴答声中解决。 (基本上,在所有当前同步代码都已执行之后,并且在服务器可以将任何数据发送回您之前很久)

第二个:变异对象是不受欢迎的,因为(精神上)很难跟踪所有可能受到这种变化影响的地方;因此很危险。最好返回带有更改的副本。

第三:保持简单 callapi 在需要了解 context 的任何地方都不会做任何事情

【讨论】:

    【解决方案2】:

    NPM库deasync解决问题:

    module.exports = async function (context, req) {    
        var uri = <uri>;
        var source = get_source_at(uri)
        context.res = { body: { "data": [{"value": source}] } };
    
    };
    
    function get_source_at(uri){
        var request = require("request");
        var deasync = require("deasync");
        var source;
        request({ uri:uri, headers: <headers>}
        , function (error, response, body) {
            source = body;
        });
        while(source === undefined) { //wait until async HTTPS request has finished
            deasync.runLoopOnce();
        }
        return source;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-07-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-09
      • 1970-01-01
      相关资源
      最近更新 更多