Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/41.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 在单独的函数中使用节点中回调的结果_Javascript_Node.js_Q - Fatal编程技术网

Javascript 在单独的函数中使用节点中回调的结果

Javascript 在单独的函数中使用节点中回调的结果,javascript,node.js,q,Javascript,Node.js,Q,我可能在这里遗漏了要点,所以我在寻求建议 我有一个nodejs服务器,它正在监听客户端连接,并根据接收到的数据调用API 对该API的第一次调用将获得一个ID,该ID需要在后续调用中使用以将它们组合在一起 我所挣扎的是,对API的调用必然是异步的,在回调中,我将ID分配给一个变量。虽然API服务器正在处理该异步调用,但从客户端传入的数据越来越多,需要进行更多的API调用,但在知道第一次调用的结果之前,我无法启动它们,因为第二次调用依赖于此 正确的处理方法是什么?我觉得我应该使用Q来保证第一个AP

我可能在这里遗漏了要点,所以我在寻求建议

我有一个nodejs服务器,它正在监听客户端连接,并根据接收到的数据调用API

对该API的第一次调用将获得一个ID,该ID需要在后续调用中使用以将它们组合在一起

我所挣扎的是,对API的调用必然是异步的,在回调中,我将ID分配给一个变量。虽然API服务器正在处理该异步调用,但从客户端传入的数据越来越多,需要进行更多的API调用,但在知道第一次调用的结果之前,我无法启动它们,因为第二次调用依赖于此

正确的处理方法是什么?我觉得我应该使用Q来保证第一个API调用的结果是第二个API调用的结果,但我不确定它应该如何构造。或者我应该将API调用排队,直到第一次调用完成?我该怎么做

问题代码示例:

var server = net.createServer();

//set up the callback handler 

server.on('connection', handleConnection);

handleConnection(conn) {
  //do some stuff...
  firstAPICall();
  conn.on('data', handleData);
}

handleData(data) {
  //do some stuff...
  otherAPIcall();
}

firstAPICall() {
  client.get("http://myAPI/getID", function (data, response) {
    conn.myID = data[0].myID;
    }
  }
}

otherAPICall() {
  //How do I make sure I actually have a value
  //in conn.myID from the first function???
  client.post("http://myAPI/storeData", { data: {myID:conn.myID, data:someData} }, function (data, response) {
    //do some stuff...
    }
  }
}

尝试使用承诺。然后使用“Then”调用otherAPICall()

我想您可以假设他们在连接后会立即发送数据。因此,您可以简化并签入otherAPICall,如果您有ID,则可以使用回调。承诺或
async/await
关键字可能会让事情变得更好,但这不是必需的

var server = net.createServer();

//set up the callback handler 

server.on('connection', handleConnection);

handleConnection(conn) {
  conn.on('data', handleData(connm, data));
}

handleData(conn, data) {
  //do some stuff...
  otherAPIcall(conn);
}

checkID(conn, cb) {
  if (!conn.myID) {
    client.get("http://myAPI/getID", function (data, response) {
      conn.myID = data[0].myID;
      cb();
    });
  } else {
    cb();
  }
}

otherAPICall(conn) {
  checkID(conn, function() {
    client.post("http://myAPI/storeData", { data: {myID:conn.myID, data:someData} }, function (data, response) {
      //do some stuff...
    });
  });
}

是的,你应该为此使用承诺。承诺从第一次调用异步解析的id,然后在后续调用中使用它:

handleConnection(conn) {
  //do some stuff...
  var idPromise = firstAPICall();
  conn.on('data', function handleData(data) {
    //do some stuff...
    otherAPIcall(idPromise).then(function(result) {
      …
    });
  });
}

firstAPICall() {
  return Q.Promise(function(resolve, reject) {
    client.get("http://myAPI/getID", function (data, response) {
      resolve(data[0].myID);
    });
  });
}

otherAPICall(idPromise) {
  return idPromise.then(function(myID) {
    return new Promise(function(resolve, reject) {
      client.post("http://myAPI/storeData", {
        data: {myID:myID, data:someData}
      }, function (data, response) {
        //do some stuff...
        resolve(…);
      });
    });
  });
}

也许你应该考虑为
客户端的结果创建一个承诺。在一个额外的函数中获得
调用。还要确保正确处理错误,并调用
reject
。如果
客户端
将使用节点回调约定,Q甚至会使用。

承诺可以链接值,并且总是在回调发生后使用返回值进行解析

function async(value) { 
var deferred = $q.defer();
var asyncCalculation = value / 2;
deferred.resolve(asyncCalculation);
return deferred.promise;
}

var promise = async(8) 
.then(function(x) {
    return x+1;
})
.then(function(x) {
    return x*2;
})
.then(function(x) {
    return x-1;
});
promise.then(function(x) { 
console.log(x);
});

此值将通过所有成功回调,因此将记录值9((8/2+1)*2-1)。

缺少的一点是“对该API的第一次调用将获得一个ID,该ID需要在后续调用中使用以将它们组合在一起”。要么是要求,要么不是。下定决心是的,承诺就是这样起作用的,但是这和问题有什么关系呢?顺便说一句,OP使用的是Q,而不是棱角分明的承诺。这个案例展示了承诺是如何起作用的,以及如何使用它。如果我理解promise,无论Q或Angularjs$Q,它们都基于相同的原则。如果你明白承诺是如何起作用的,为什么你不能在其他领域使用它。我最终还是用了承诺,它似乎很有效——谢谢!