JavaScript /异步函数调用在函数返回之前是否有阻塞的简写?

时间:2017-08-24 19:45:28

标签: javascript asynchronous

在Javascript中,(如果有帮助的节点环境),我有一些函数需要查询不同的数据库并使用组合数据。因为它们都是异步的,所以它会产生一些非常混乱的嵌套代码(例如)

database1.find(options, function(docs){
    docs1 = docs;
    database2.find(options, function(docs){
        docs2 = docs;
        database3.find(options, function(docs){
            docs3 = docs;
            //do things with docs1, docs2, docs3
        });
    });
});

有没有办法编写一个包装器(或者可能是一个库已经存在),它可以让我写一些东西来调用该函数,并阻塞它直到它返回所请求的值?

docs1 = waitUntilDone(database1.find(options, function(docs)));
docs2 = waitUntilDone(database1.find(options, function(docs)));
docs3 = waitUntilDone(database1.find(options, function(docs)));
//do things with docs1, docs2, docs3

3 个答案:

答案 0 :(得分:2)

使用Promises包裹您的函数并使用async / await语法(async function)。

示例(使用您的代码):

const find = (database, options) => new Promise((resolve, reject) => {
  database.find(options, (docs) => {
    //error checking
    if(docs.error) return reject(docs.error);

    resolve(docs);
  });
});

(async () => {
  const options = {};

  const docs1 = await find(database1, options);
  const docs2 = await find(database2, options);
  const docs3 = await find(database3, options);
});

答案 1 :(得分:-1)

对于控制流程,我通常使用async库。看一下async.waterfall()函数;它允许你串行执行n个函数,每个函数都将结果传递给下一个函数。

以下是一个例子:

async.waterfall([
    function(callback) {
        callback(null, 'one', 'two');
    },
    function(arg1, arg2, callback) {
        // arg1 now equals 'one' and arg2 now equals 'two'
        callback(null, 'three');
    },
    function(arg1, callback) {
        // arg1 now equals 'three'
        callback(null, 'done');
    }
], function (err, result) {
    // result now equals 'done'
});

答案 2 :(得分:-1)

首先,您应该避免在JS中使用同步方法。 JS的异步特性是该语言的最佳特性之一。

至少有3种避免回旋码的方法:promises,yield(generator)和async / await。

第一种方法可以在任何浏览器中使用而无需转换。看看BlueBird库。它会让你的生活更轻松。最高级的选项是使用async / await语言构造。唉,你需要使用transpiler,例如Babel JS。

祝你好运!