等待nodejs

时间:2017-11-12 06:29:05

标签: javascript node.js

我正在开发一个nodejs应用程序,需要从数组中获取设置(在设置对象中),根据设置调用rest api并将响应写入mongodb并重复此操作以进行数组中的下一个设置。 / p>

以下是应用程序的简化版本

var setting //global
process(){ //top level function
    for(let s of config.settings){
    setting = s;
    getData();
  }
}

function getData(){
    init()
    .then(makeRequest)      // constructs and makes the rest api call
    .then(insert)           // writes the response to the db
    .catch(function(err){   
    // logs err
   }
}

运行它,只有最后一个设置(在数组中)的数据被写入db,每次迭代都会发生这种情况。基本上,相同的数据会在db上写入多次迭代。 我可以从中看到的问题是,在promises返回值之前,for循环完成执行。 我见过一些async.for的例子 有关解决此问题的任何建议你如何设计这种流程?

3 个答案:

答案 0 :(得分:2)

您可以将设置绑定到每个函数调用以保留该值。虽然我不确定您的代码是伪代码还是实际代码,但看起来您必须重构,因为值会作为参数传递。

async await也可以正常工作,但会花费更长时间,因为它会在每次api调用时暂停执行。

答案 1 :(得分:2)

您应该返回一个可用于存储请求内部状态的对象或数组。请参阅示例了解其工作原理。

也永远不要设置一个全局变量来存储你的状态,你的函数是异步的,这个值可能不是你想象的那样。

使用这种方法,您将传递{ init }作为第一个承诺,然后传递{ init, request }作为下一个承诺,这样您就可以从承诺链的每个部分获得响应,以便进一步请求。< / p>

// return an object to store the state on init
const init = () => 
  new Promise((res, rej) => res({
    init: 'initted'
  }))

// pass init and the request to the next function in the chain
const makeRequest = ({ init }) => 
  new Promise((res, rej) => res({
    init,
    request: {
      msg: 'this is the response', 
      id: 33
    }
  }))
 
// insert stuff from the request
// then return the data to the next query
const insert = ({ init, request }) =>
  new Promise((res, rej) => res({
    request, 
    init,
    created_at: Date.now()
  }))
  
const trace = name => x => (console.log(name, x), x)

function getData(){
  return init() // return your promise so you can chain it further
    .then(trace('after init'))
    .then(makeRequest)
    .then(trace('after request'))
    .then(insert)
    .then(trace('after insert'))
    .catch(console.error)
}

// call you function
getData()
  // since the promise is returned we can continue the chain
  .then(state => console.log({ state }))
<script src="https://codepen.io/synthet1c/pen/KyQQmL.js"></script>

答案 2 :(得分:1)

所有循环都将在回调进入时执行。因此$(document).ready(function() { var table = document.getElementById("userstable"); var rowCount = table.rows.length; for (i = 1; i <= rowCount; i++) { alert($('#userstable tr:eq(1) td:eq(0) input').val()); } }); 将是最后一个值。

不是依赖于全局变量,而是将设置传递给getData,例如。