2016-03-07 3 views
0

Я новичок в концепции Generator. Я понимаю, что если функция возвращает Promise, то ее можно использовать с yield. Так что у меня очень маленький Node.js скрипт, который выглядит следующим образом:Как использовать выход с моими собственными функциями?

Q.fcall(function*(){ 
    var url = "mongodb://" + config.host + ":" + config.port + "/" + config.db; 
    var db = yield MongoClient.connect(url); 
    var data = yield makeRequest(); 
    console.log(data); 
    db.close(); 
}); 


function makeRequest(){ 
    var deferred = Q.defer(); 
    request({ 
     "method" : "GET", 
     "url" : "....", 
     "headers" : { 
      "Accept" : "application/json", 
      "user_key" : "...." 
     } 
    },function(err,data){ 
     if(err){ 
      deferred.reject(err); 
     }else{ 
      deferred.resolve(data); 
     } 
    }); 
    return deferred.promise; 
} 

Я знаю, что это работает, потому что я его перенос из стиля ада обратного вызова в генератор стиля. Однако я не вижу данные в console.log.

Что мне нужно изменить, чтобы сделать эту работу?

+0

* «Я понимаю, что если функция возвращает Promise, то ее можно использовать с' yield'. »* Генераторы (и' yield') не имеют ничего общего с обещаниями. Они могут использоваться вместе, чтобы реализовать что-то вроде 'async/await', но' yield' сам по себе не рассматривает обещания иначе, чем любое другое значение. –

+0

Это должно ответить на ваш вопрос: [Что происходит, когда обещание дается в javascript?] (Http://stackoverflow.com/q/33947850/218196) –

+0

@FelixKling спасибо! Я читал этот http://stackoverflow.com/questions/17516952/trying-to-understand-generators-yield-in-node-js-what-executes- the-asynchron?rq=1, когда вы его разместили :) –

ответ

1

Q.fcall не подходит для работы с функциями генератора. Вы должны использовать dedicated generator methods для этого, в вашем случае Q.spawn:

Q.spawn(function*() { 
    var url = "mongodb://" + config.host + ":" + config.port + "/" + config.db; 
    var db = yield MongoClient.connect(url); 
    try { 
    var data = yield makeRequest(); 
    console.log(data); 
    } finally { 
    db.close(); 
    } 
}); 

Без бегун, генератор не будет автоматически расширенный асинхронно.

1

Рассмотрите возможность использования co, который может обернуть генераторы и сделать вызываемым. Он возвращает обещание.

const co = require('co'); 
const promisedGenerator = co.wrap(function*() { 
    yield whatever1(); 
    yield whatever2(); 
    return databaseRequest(); 
}); 

promisedGenerator() 
    .then(databaseResult => { 
    console.log(databaseResult); 
    }); 

 Смежные вопросы

  • Нет связанных вопросов^_^