node.js 中的嵌套承诺是否正常? [英] Are nested promises normal in node.js?

查看:27
本文介绍了node.js 中的嵌套承诺是否正常?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在学习 node.js 的过程中已经纠结了两个星期的问题是如何使用 node.js 进行同步编程.我发现无论我如何尝试按顺序做事,我总是以嵌套的 promise 告终.我发现有诸如 Q 之类的模块可以帮助实现可维护性方面的承诺链.

The problem I have been struggling with for two weeks now while learning node.js is how to do synchronous programming using node. I found that no matter how I try to do things sequentially I always end up with nested promises. I have found that there are modules such as Q to help with promise chaining as far as maintainability.

我在做研究时不明白的是Promise.all()Promise.resolve()Promise.reject()>.Promise.reject 顾名思义,但在编写应用程序时,我对如何在不破坏应用程序行为的情况下在函数或对象中包含任何这些内容感到困惑.

What I don't understand while doing research is Promise.all(), Promise.resolve() and Promise.reject(). Promise.reject is pretty much self explanatory by the name but when writing an application I am confused on how to include any of these in functions or objects without breaking the behavior of the application.

当来自 Java 或 C# 等编程语言时,node.js 肯定有学习曲线.仍然存在的问题是在 node.js 中 promise 链接是否正常(最佳实践).

There is definitely a learning curve to node.js when coming from a programming language such as Java or C#. The question that still resides is if promise chaining is normal (best practice) in node.js.

示例:

driver.get('https://website.com/login').then(function () {
    loginPage.login('company.admin', 'password').then(function () {
        var employeePage = new EmployeePage(driver.getDriver());

        employeePage.clickAddEmployee().then(function() {
            setTimeout(function() {
                var addEmployeeForm = new AddEmployeeForm(driver.getDriver());

                addEmployeeForm.insertUserName(employee.username).then(function() {
                    addEmployeeForm.insertFirstName(employee.firstName).then(function() {
                        addEmployeeForm.insertLastName(employee.lastName).then(function() {
                            addEmployeeForm.clickCreateEmployee().then(function() {
                                employeePage.searchEmployee(employee);
                            });
                        });
                    });
                });
            }, 750);
        });
    });
});

推荐答案

不,Promises 的一大优点是您可以保持异步代码线性而不是嵌套(持续传递风格的回调地狱).

No, one of the great advantages of Promises is that you you can keep your async code linear rather than nested (callback hell from continuation passing style).

>

Promise 为您提供 return 语句和错误抛出,而在继续传递样式中您会丢失这些.

Promises give you return statements and error throwing, which you lose with continuation passing style.

您需要从异步函数返回承诺,以便您可以链接返回的值.

You need to return the promise from your async functions so you can chain on the returned value.

这是一个例子:

driver.get('https://website.com/login')
  .then(function() {
    return loginPage.login('company.admin', 'password')
  })
  .then(function() {
    var employeePage = new EmployeePage(driver.getDriver());
    return employeePage.clickAddEmployee();
  })
  .then(function() {
    setTimeout(function() {
      var addEmployeeForm = new AddEmployeeForm(driver.getDriver());

      addEmployeeForm.insertUserName(employee.username)
        .then(function() {
          return addEmployeeForm.insertFirstName(employee.firstName)
        })
        .then(function() {
          return addEmployeeForm.insertLastName(employee.lastName)
        })
        .then(function() {
          return addEmployeeForm.clickCreateEmployee()
        })
        .then(function() {
          return employeePage.searchEmployee(employee)
        });
    }, 750);
});

Promise.all 接受一组承诺并在所有承诺解决后解决,如果有任何承诺被拒绝,则该数组被拒绝.这允许您并发而不是串行执行异步代码,并且仍然等待所有并发函数的结果.如果您对线程模型感到满意,请考虑生成线程然后加入.

Promise.all takes an array of promises and resolves once all promises resolve, if any are rejected, the array is rejected. This allows you to execute async code concurrently rather than serially, and still wait for the result of all concurrent functions. If you're comfortable with a threaded model, think spawning threads and then joining.

示例:

addEmployeeForm.insertUserName(employee.username)
    .then(function() {
        // these two functions will be invoked immediately and resolve concurrently
        return Promise.all([
            addEmployeeForm.insertFirstName(employee.firstName),
            addEmployeeForm.insertLastName(employee.lastName)
        ])
    })
    // this will be invoked after both insertFirstName and insertLastName have succeeded
    .then(function() {
        return addEmployeeForm.clickCreateEmployee()
    })
    .then(function() {
        return employeePage.searchEmployee(employee)
    })
    // if an error arises anywhere in the chain this function will be invoked
    .catch(function(err){
        console.log(err)
    });

Promise.resolve()Promise.reject() 是创建 Promise 时使用的方法.它们用于使用回调包装异步函数,以便您可以使用 Promise 而不是回调.

Promise.resolve() and Promise.reject() are methods used when creating a Promise. They're used to wrap an async function using callbacks so that you can work with Promises instead of callbacks.

Resolve 将解析/履行承诺(这意味着将使用结果值调用链式 then 方法).
Reject 将拒绝承诺(这意味着不会调用任何链接的 then 方法,但将调用第一个链接的 catch 方法与出现的错误).

Resolve will resolve/fulfill the promise (this means a chained then method will be called with the resulting value).
Reject will reject the promise (this means any chained then method(s) will not be called, but the first chained catch method will be called with the error that arose).

我保留了您的 setTimeout 以保留您的程序行为,但这可能是不必要的.

I left your setTimeout in place to preserve your programs behavior, but it's likely unnecessary.

这篇关于node.js 中的嵌套承诺是否正常?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆