2015-09-30 2 views
0

У меня есть библиотека nodejs, написанная с использованием модуля async/await. Я пытаюсь использовать его из библиотеки, которая использует регулярные обратные вызовы. Вот пример кода:вызов asyncwait из обратного вызова

var async = require('asyncawait/async'); 
var await = require('asyncawait/await'); 
var Promise = require('bluebird'); 

var foo = async (function() { 
    var resultA = await (Promise.promisify(bar)); 
    return 111; 
}) 

function bar(callback) { 
    setTimeout(callback, 2000) 
} 

function moo() { 
    var f = async.cps(foo) 

    f(function(err, res) { 
    console.log(res) 
    }) 

} 

moo() 

Я ожидал console.log напечатать 111, но вместо этого она печатает:

{ _bitField: 0, 
    _fulfillmentHandler0: undefined, 
    _rejectionHandler0: undefined, 
    _progressHandler0: undefined, 
    _promise0: undefined, 
    _receiver0: undefined, 
    _settledValue: undefined } 

Кстати, если я встраивать реализацию Foo в «async.cps» линии это работает (но это не вариант с его внешней библиотеки).

Любая идея?

ответ

1

Я посмотрел на библиотеку, которую вы используете, и по внешнему виду (там мало и, конечно, нет рабочих образцов), вы не используете ее правильно.

async(fn) вернет функцию, которая принимает некоторые входные значения, и после исполнения вернет обещание (возможно, standard Promises/A+). Внутри он будет вызывать fn с входными параметрами и будет разрешать возвращенное обещание при возврате fn.

async.cps(...) возвращает функцию, которая принимает некоторые входные значения и функция обратного вызова узла типа (function (err, res)) и при выполнении будет возвращать пустоту (undefined). Внутри он вызовет fn с входными параметрами и вызовет функцию обратного вызова, когда fn вернулась с соответствующими значениями.

Что делает ваш код, это создать функцию с async(fn), а затем передать эту функцию в async.cps(..), как если бы вы вызвали async.cps(async(fn)), но это не имеет никакого смысла.

Что вы могли бы сделать, если вы хотите, чтобы «преобразовать» обещание функции типа узла обратного вызова (! Unpromisifying) с помощью этой библиотеки заключается в следующем:

function moo() { 
    var f = async.cps(function() { 
    return await (foo()) 
    }) 

    f(function(err, res) { 
    console.log(res) 
    }) 
} 
1

Вы дважды asynced функция foo. Вот варианты, в зависимости от того, можно ли изменить декларацию foo или нет:

Оставить foo асинхр и создать функцию f, которая принимает функцию обратного вызова узла стиле с использованием cps:

var async = require('asyncawait/async'); 
var await = require('asyncawait/await'); 
var Promise = require('bluebird'); 

var foo = async(function() { 
    var resultA = await (Promise.promisify(bar)); 
    return 111; 
}); 

function bar(callback) { 
    setTimeout(callback, 1000); 
} 

function moo() { 
    var f = async.cps(function() { 
    return await(foo()); 
    }); 
    f(function(err, res) { 
    console.log(res); 
    }); 
} 

moo(); 

Leave foo асинхронные и использовать асинхра moo:

var async = require('asyncawait/async'); 
var await = require('asyncawait/await'); 
var Promise = require('bluebird'); 

var foo = async(function() { 
    var resultA = await (Promise.promisify(bar)); 
    return 111; 
}); 

function bar(callback) { 
    setTimeout(callback, 1000); 
} 

var moo = async(function() { 
    try { 
    var res = await(foo()); 
    console.log(res); 
    } catch (err) { 
    } 
});  

moo(); 

Сделать foo уже cps в объявлении:

var async = require('asyncawait/async'); 
var await = require('asyncawait/await'); 
var Promise = require('bluebird'); 

var foo = async.cps(function() { 
    var resultA = await (Promise.promisify(bar)); 
    return 111; 
}); 

function bar(callback) { 
    setTimeout(callback, 1000); 
} 

function moo() { 
    foo(function(err, res) { 
    console.log(res); 
    }); 
} 

moo(); 
Смежные вопросы