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

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

问题描述

我在学习node.js的过程中遇到了两个星期的问题,就是如何使用node进行同步编程。我发现无论我如何尝试按顺序执行 ,我总是以嵌套的承诺结束。我发现有一些像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肯定存在学习曲线。仍然存在的问题是如果promise.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).

Promises给你返回语句和错误抛出,你会因为继续传递而丢失样式。

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 时使用的方法。它们用于使用回调包装异步函数,以便您可以使用Promises而不是回调。

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 将解决/实现promise(这意味着将使用结果值调用链式然后方法)。

拒绝将拒绝承诺(这意味着将不会调用任何链接的然后方法,但将调用第一个链接的 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中嵌套的promises是否正常?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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