javascript - NODE - 等待一个 api 调用完成后再触发下一个 api 调用

标签 javascript node.js asynchronous

我正在我的路由添加用户之一中发出 POST 请求。我创建了一个名为 success 的数组。一旦请求返回响应,我想触发下一个 API 调用。

目前无法正常工作,因为我认为我一次发送的 API 请求太多。我认为解决方案是等待第一个响应返回响应并完成,然后触发下一个 API 调用。

这个假设正确吗?如果是这样,有人可以建议如何实现吗?我尝试使用 .on('end'....

请参阅下面我的代码。

app.get('/add-users', function (req, res) {

    var success = [];
    var count = 0;
    for(var i = 0; i < users.length; i++) {
        var name = users[i].userId;
        request({
            url: url,
            headers: {
                'Authorization': 'Bearer ' + users[i].accessToken,
                'Content-Type': 'application/json'
            },
            method: 'PUT',
            json: true
        }, function(err, resp, body){
            if (!err && resp.statusCode === 200) {
                success.push(name);
            }
        })
        .on('end', function(){
            console.log('this is the end');
            count++;
            if(count === users.length) {
                res.json(success);
            }
        });
    }
});

最佳答案

经典!当我第一次处理 Node 时,我也遇到过这个问题。

让我先复制代码的某些部分来解释一下:

app.get('/add-users', function (req, res) {
    // [...]
    for(/* user in users */) {
        request(/* [...] */)
        .on('end', function(){
            console.log('this is the end');
            count++;
            if(count === users.length) {
                res.json(success);
            }
        });
    }
});

与其他语言(例如 Ruby)相比,Node 执行非阻塞 I/O。这意味着它几乎异步执行所有 I/O 操作(例如发出 HTTP 请求)。本质上,当您发起请求时,它不会等待响应。

在循环中,这意味着它将依次触发所有请求,而不等待它们的响应:

start loop
  make request
  make request
  make request
end of loop

... a little later
handle response
handle response
handle response

我假设你想要的看起来像这样:

start loop
  make request
  handle response
  make request
  handle response
  make request
  handle response
end of loop

我发现绕过 Node 的非阻塞特性并执行顺序请求的一个技巧是编写如下的递归函数:

function getAllUsers(users) {
    function getOneUser(users) {
        let user = users.pop();
        request(/* [...] */)
            .on('end', function() {
                console.log("done with ONE user");
                if(users.length) { // do we still have users to make requests?
                    getOneUser(users); // recursion
                } else {
                    console.log("done with ALL users");
                    res.json(success);
                }
            });
    }

    // make a copy of the original users Array because we're going to mutate it
    getOneUser(Array.from(users)); 
}

上面的操作是为一个用户发出一个请求,然后当响应到达时触发另一个请求。

我希望这会有所帮助。

关于javascript - NODE - 等待一个 api 调用完成后再触发下一个 api 调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41743123/

相关文章:

node.js - 如何为 Sails.js 中的所有 Controller 添加方法?

c++ - 如何将异步计时器添加到 boost UDP 服务器?

android - 如何在不阻塞的情况下等待 Android UI 线程中异步填充的对象?

javascript - 当 Firestore.getAll(...promises) 因拒绝而停止时如何 "control"

javascript - 鼠标悬停和鼠标离开外部 div

javascript - 无法读取 JSON 响应,整数变为 NULL

node.js - 如何永久执行 npm run 命令

c# - Controller 的非异步方法是否会阻止其他用户在使用或锁定时进入?

javascript - 从 JS 访问 REST API

javascript - IE7/8 就绪状态 3 中的响应文本不可用