Promise Object

A promise is a JavaScript object that represents the eventual result of an asynchronous process. After the promise object is created, it serves as a placeholder for the future success or failure of the asynchronous process. While the promise object is waiting, the remaining segments of the script can execute. With promises, developers can write asynchronous code that is intuitive and efficient.

A promise holds one of the following values:

When it is first created, a promise holds the value pending. After the associated process is complete, the value changes to fulfilled for a successful completion or to rejected for an unsuccessful completion. A success or failure callback function attached to the promise is called when the process is complete. Note that a promise can only succeed or fail one time. When the value of the promise updates to fulfilled or rejected, it cannot change.

SuiteScript 2.x provides promise APIs for selected modules as listed in SuiteScript 2.x Promise APIs. In SuiteScript 2.x, all client scripts support the use of promises, and starting with NetSuite 2021.1, a subset of server scripts also support the use of promises. Custom promises can also be created for client scripts (see Custom Promises).

Starting in NetSuite 2021.1, SuiteScript 2.1 supports non-blocking asynchronous server-side promises expressed using the asnyc, await, and promise keywords for a subset of modules: N/http, N/https, N/query, N/search, and N/transaction. This allows developers to upload and deploy a SuiteScript 2.1 script that includes the async, await, and promise keywords. For more information about SuiteScript versions and SuiteScript 2.1, see SuiteScript Versioning Guidelines and SuiteScript 2.1.

When using server-side promises in SuiteScript 2.1, you should consider the following:

When you code your SuiteScript scripts to be asynchronous, you should also consider following best practices. A few best practices are included in Best Practices for Asynchronous Programming with SuiteScript.

For more information about JavaScript promises, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise.

Best Practices for Asynchronous Programming with SuiteScript

When using promises in your SuiteScript scripts to implement asynchronous programming, you should consider the following best practices. If you are using SuiteScript 2.1 scripts, consider using the async and await keywords to implement asynchronous solutions instead of using the promise keyword.

For additional best practices for SuiteScript scripts, see SuiteScript Best Practices.

Best practices for coding promises:

  • Always use a promise rejection by including a promise.catch handler.

  • Do not nest promises. Chain your promises instead. Or use async/await functionality.

  • Keep promise chains short to avoid significant overuse of memory and CPU.

  • Use promise.finally if you have code that should run regardless of the outcome of the promise.

  • Use promise.all for multiple unrelated asynchronous calls.

  • Do not define rejection handlers as the second argument for promise.then calls. Instead, use promise.catch.

  • If you need to access results of promises running in parallel, use promise.spread.

  • To limit concurrency, use promise.map.

  • Use promise.then to run code after the promise completes.

For additional best practice guidance when coding promises, see Best Practices for ES6 Promises, Best Practices for Using Promises in JS, JavaScript Promises Tips and Tricks, Promises (Mozilla), JavaScript Best Practices for Promises, and Promises.

Best practices when using async and await keywords:

  • Rewrite promise code to use async/await.

  • Schedule first, await later.

  • Avoid mixing callback-based APIs with promise-based APIs.

  • Refrain from using return await.

For additional best practice guidance when using async/await, see Best Practices for ES2017 Asynchronous Functions, and Making asynchronous programming easier with async and await.

SuiteScript 2.x Promise APIs

The available promise APIs are named so that they correspond with their synchronous counterparts. Promise APIs have names that are suffixed with .promise. For example, the search.create(options) API has a promise version named search.create.promise(options). The following promise APIs are supported for 2.x client scripts and 2.1 server scripts:

Module

Promise API

Supported in SuiteScript 2.x Client Scripts

Supported in SuiteScript 2.1 Server Scripts

N/action Module

Action.promise(options)

checkmark

Action.execute.promise(options)

checkmark

action.execute.promise(options)

checkmark

action.find.promise(options)

checkmark

action.get.promise(options)

checkmark

N/currentRecord Module

currentRecord.get.promise()

checkmark

N/email Module

email.send.promise(options)

checkmark

email.sendBulk.promise(options)

checkmark

email.sendCampaignEvent.promise(options)

checkmark

N/http Module

http.delete.promise(options)

checkmark

checkmark

http.get.promise(options)

checkmark

checkmark

http.post.promise(options)

checkmark

checkmark

http.put.promise(options)

checkmark

checkmark

http.request.promise(options)

checkmark

checkmark

N/https Module

https.get.promise(options)

checkmark

checkmark

https.post.promise(options)

checkmark

checkmark

https.put.promise(options)

checkmark

checkmark

https.request.promise(options)

checkmark

checkmark

https.requestSuitelet.promise(options)

checkmark

checkmark

N/query Module

Query.run.promise()

checkmark

checkmark

Query.runPaged.promise()

checkmark

checkmark

query.load.promise(options)

checkmark

checkmark

N/record Module

Macro.execute.promise(options)

checkmark

Macro.promise(options)

checkmark

Record.executeMacro.promise(options)

checkmark

Record.save.promise(options)

checkmark

record.attach.promise(options)

checkmark

record.copy.promise(options)

checkmark

record.create.promise(options)

checkmark

record.delete.promise(options)

checkmark

record.detach.promise(options)

checkmark

record.load.promise(options)

checkmark

record.submitFields.promise(options)

checkmark

record.transform.promise(options)

checkmark

N/search Module

Page.next.promise()

checkmark

Page.prev.promise()

checkmark

PagedData.fetch.promise()

checkmark

ResultSet.each.promise(callback)

checkmark

ResultSet.getRange.promise(options)

checkmark

Search.runPaged.promise(options)

checkmark

checkmark

Search.save.promise()

checkmark

checkmark

search.create.promise(options)

checkmark

checkmark

search.delete.promise(options)

checkmark

checkmark

search.duplicates.promise(options)

checkmark

checkmark

search.global.promise(options)

checkmark

checkmark

search.load.promise(options)

checkmark

checkmark

search.lookupFields.promise(options)

checkmark

checkmark

N/transaction Module

transaction.void.promise(options)

checkmark

checkmark

For supported modules members and additional API information, see SuiteScript 2.x Modules.

Examples

The following is a basic example of how to use the search.create.promise in a client script for the pageInit entry point.

          /**
* @NApiVersion 2.x
*/

define(['N/search'], function(search)
{
    function doSomething() 
    {
        search.create.promise({
            type: 'salesorder'
        })
        .then(function(result) {
            log.debug("Completed: " + result); 
            //do something after completion
        })
        .catch(function(reason) {
            log.debug("Failed: " + reason) 
            //do something on failure
        });
    }
    return 
    {
        pageInit: doSomething
    }
}); 

        

This example demonstrates how to chain promises created with SuiteScript promise APIs.

          /**
* @NApiVersion 2.x
*/
define(['N/search'], function(search) 
{
    function doSomething() 
    {
        var filter = search.createFilter({
            name: 'mainline', 
            operator: search.Operator.IS, 
            values:['T']
        });

        search.create.promise({
            type: 'salesorder', 
            filters:[filter]
        })
        .then(function(searchObj) {
            return searchObj.run().each.promise(
                function(result, index){
                //do something
            })
        })
        .then(function(result) {
            log.debug("Completed: " + result) 
            //do something after completion
        })
        .catch(function(reason) {
            log.debug("Failed: " + reason) 
            //do something on failure
        });
    })
    return 
    {
        pageInit: doSomething
    }

}); 

        

Custom Promises

The following example shows a custom promise. Note that custom promises do not use the SuiteScript 2.x Promise APIs.

          /**
* @NApiVersion 2.x
*/

define(function(){
    function doSomething(addresses){
        var promise = new Promise(function(resolve, reject){
            var url = 'https://your.favorite.maps/api/directions?start=' + addresses.start + '&end=' + addresses.end,
                isAsync = true,
                xhr = new XMLHttpRequest();

                xhr.addEventListener('load', function (event) {
                    if (xhr.readyState === 4) {
                        if (xhr.status === 200) {
                            resolve(xhr.responseText );
                        } 
                        else {
                            reject( xhr.statusText );
                        }
                    }
                });

                xhr.addEventListener('error', function (event) {
                    reject( xhr.statusText );
                });

                xhr.open('GET', url, isAsync);
                xhr.send();
            });

        return promise;
    }

    return {
        lookupDirections: doSomething
    };
}); 

        

Related Topics

General Notices