在promise中定义异步函数

时间:2017-05-29 14:38:01

标签: javascript node.js mongodb promise

我正在使用 .then 编写承诺代码。现在,我决定使用await / async编写它。我在promise中调用了一个函数 add_Lessons ,然后在该函数的 .then 中调用另一个函数。这是我的代码,使用 .then

function create_section(sections,course_ID,i) {
return new Promise(
    (resolve) => {
        var s_duration = 0;
        var sname = sections[i].name;
        var s_obj = {
            //some object;
        }
        var section_id;
        DB.section.create(s_obj,function (err, data_s) 
        {
            if (err) return next(err);
            section_id = data_s._id;
            var lesson = sections[i].lessons;
            add_lessons(lesson,section_id,i)
            .then(function(arr){
                resolve(arr);
            })
        });
    }
);
};

这是使用 await / async

的代码
function create_section(sections,course_ID,i) {
return new Promise(
    async function resolve() {
        var s_duration = 0;
        var sname = sections[i].name;
        var s_obj = {
           //some obj
        }
        var section_id;
        DB.section.create(s_obj,function (err, data_s) 
        {
            if (err) return next(err);
            section_id = data_s._id;
            var lesson = sections[i].lessons;
            var arr = await add_lessons(lesson,section_id,i)
            resolve(arr);
        });
    }
);
};

使用await / async的代码显示add_lessons是意外标识符的错误。 那么告诉我如何在promise中定义异步函数?

1 个答案:

答案 0 :(得分:4)

您将async置于错误的功能前面。此功能应为async

DB.section.create(s_obj,function (err, data_s) 
像这样:

DB.section.create(s_obj, async function (err, data_s)

您只能在具有await关键字的函数内部使用async,而不能在其他具有async关键字的函数内使用所有函数。

但是你应该传递给new Promise()构造函数的是一个函数,它将resolve作为参数而不是一个本身名为resolve的函数。而不是:

return new Promise(
    async function resolve() {

你应该使用类似的东西:

return new Promise(function (resolve, reject) {

然后你也可以运行reject代替next(error) - 所以代替:

if (err) return next(err);
你可以试试:

if (err) return reject(err);

如果您确实要拒绝从create_section()函数返回的承诺。

您正在混合三种异步控制流方式:回调,承诺和异步/等待。你需要完全理解它们,以便能够毫无问题地将它们组合起来。

我建议写一个包装器,为所有带回调的函数返回promises,如下所示:

const sectionCreate = (...args) => new Promise((resolve, reject) => {
  DB.section.create(...args, (err, data) => {
    if (err) {
      return reject(err);
    }
    resolve data;
  });
});

(或者你可以使用Bluebird' promisify) 现在,您可以轻松地在异步/等待流程中使用它:

async function create_section(sections, course_ID, i) {
    var s_duration = 0;
    var sname = sections[i].name;
    var s_obj = {
       //some obj
    }
    var section_id;
    var data = await sectionCreate(s_obj);
    var section_id = data_s._id;
    var lesson = sections[i].lessons;
    var arr = await add_lessons(lesson, section_id, i);
    return arr;
}

这假设add_lessons()返回隐含的承诺,但是您的代码却可能不是这样。你可以在promises上await,这样你就可以在返回promises的函数调用前使用await

请注意,每个async函数都会返回一个承诺,因此您不需要明确地执行此承诺。