2017-08-12 85 views
-2

我知道承诺是我的问题的答案,但需要帮助在我的情况下如何使用。nodejs等待被调用的函数http请求完成之前从被调用者返回

我的代码是:

... 

invoke: (abc) => { 
    module.exports.getData(); 
    return; 
}, 

getData:() => { 
    request(options, function(err, res, body) { 
    if (res && (res.statusCode === 200 || res.statusCode === 201)) { 
     logger.info("vacation balacne response:" + body); 
    } 
    }); 
}, 

... 

所以在我目前的状况,invoke方法不会等待的getData完成。我需要从getData中的调用返回响应数据,并在invoke方法中使用它。请指教。

+0

你不能让'getData()'等待结果(因为Javascript异步操作的方式)并且你不能直接从'getData()'返回结果,因为它是异步的并且函数返回LONG之前异步结果可用。相反,您可以返回一个承诺,然后调用者可以使用promise上的'.then()'方法来检索结果。我已经标记了这个重复的答案向你展示了如何做到这一点,并且还有数百篇关于如何“促成”某些事情的其他文章,以使其返回一个承诺。 – jfriend00

+0

你如何做到这一点?示例plz – Vik

+0

有一篇关于如何在[你被标记为重复的问题的接受答案](https://stackoverflow.com/a/14220323/816620)中做到这一点的LONG论文。去阅读并研究所有这些。链接到你的问题标题下方。标记重复的地方在于,我们不打算再次复制关于此主题的另一个问题中所写的全部内容。在这里每天都会发布几十种这样的问题,因为它是为大多数刚刚接触node.js的人开发的新方法。必须学习。 – jfriend00

回答

0

不知道有关语法,但你可以调用方法里面的getData功能同步 -

invoke: (abc) => { 
     module.exports.getData(function(err,result){ 
     if(err) // do something 
     else // do something 
     return; 
     }); 
    }, 
    getData:(callback) => { 
    request(options, function(err, res, body) { 
      if (res && (res.statusCode === 200 || res.statusCode === 201)) { 
        logger.info("vacation balacne response:" + body); 
        return callback(null,body); 
       } 
      else return callback(err,null); 
      }); 

} 

希望它能帮助!

0

当然不会,它是一个异步功能。最简单的办法是做回调摆脱getDatainvoke,以便调用可以通过它进入的getData,然后的getData可以叫做“无论你需要有持续下去。”一旦数据可用:

var Thing = { 
    .... 

    invoke: (andThenDoThis) => { 
    Thing.getData(andThenDoThis); 
    }, 

    getData: (andThenDoThis) => { 
    request(options, function(err, res, body) { 
     if (res && (res.statusCode === 200 || res.statusCode === 201)) { 
     logger.info("vacation balacne response:" + body); 
     } 

     // THIS IS WHERE YOUR CODE WILL NOW CONTINUE: 
     if (andThenDoThis) { 
     andThenDoThis(err, res, body) 
     } 
    }); 
    }, 
    ... 
}; 

虽然当然这是愚蠢的,因为只是定义对象与this引用来代替:

class Thing { 
    constructor(options) { 
    this.options = options; 
    } 

    invoke() { 
    this.getData((err, res, body) => { 
     this.handleData(err, res, body); 
    }); 
    } 

    getData(andThenDoThis) { 
    request(this.options, (err, res, body) => { 
     this.handleData(err, res, body) 
    }); 
    } 

    handleData(err, res, body) { 
    // do some `err` checking 
    // do some `res` checking 
    // do some `body` parsing 
    // do whatever else 
    if (this.options.forwardData) { 
     this.options.forwardData(...); 
    } 
    } 

    ... 
} 

然后就是做这些事情之一:

// make a thing: 
let thing = new Thing({ 
    ..., 
    forwardData: (data) => { 
    // do whatever with your data. 
    }, 
    ... 
}); 

// and then invoke whatever it is you actually needed to do. 
thing.invoke(); 

// code here keeps running, but that's fine, because now you're 
// using "code triggers only when, and where, it needs to".